©SoftMoore Consulting
The UI Thread
• When an application is launched, the system creates a “main” UI thread responsible for handling interaction with running components of the Android UI toolkit.
• Performing long operations such as network access or database queries on the UI thread will block the whole user interface.
• From the user's perspective, the application appears hung. Even worse, if the UI thread is blocked for more than a few seconds, the user is presented with the infamous “application not responding” (ANR) dialog.
• To keep the UI thread responsive, long operations should be performed in background/worker threads.
Slide 2
©SoftMoore Consulting
The UI Single-Thread Model
Two rules for using the UI single-thread model:
1. Do not block the UI thread.
2. The Android UI toolkit is not thread-safe and must always be manipulated on the UI thread.
Slide 3
©SoftMoore Consulting
Example: Downloading a Bitmap Image(Violates Rule #1)
public void onClick(View v) { Bitmap b = loadImageFromNetwork(); myImageView.setImageBitmap(b); }
Slide 4
The user interface is blocked while theimage is downloading from the Internet.
©SoftMoore Consulting
Example: Downloading a Bitmap Image(Violates Rule #2)
public void onClick(View v) { new Thread(new Runnable() { public void run() { Bitmap b = loadImageFromNetwork(); myImageView.setImageBitmap(b); } }).start(); }
Slide 5
myImageView is manipulated on aworker thread, not the UI thread.
©SoftMoore Consulting
Accessing the UI Thread from Other Threads
Android offers several ways to access the UI thread from other threads.
• Activity.runOnUiThread(Runnable)
• View.post(Runnable)
• View.postDelayed(Runnable, long)
• Handler
• AsyncTask
Slide 6
©SoftMoore Consulting
Using the View.post(Runnable) Method
public void onClick(View v) { new Thread(new Runnable() { public void run() { final Bitmap bitmap = loadImageFromNetwork();
myImageView.post(new Runnable() { public void run() { myImageView.setImageBitmap(bitmap); } }); } }).start(); }
Slide 7
worker thread − codenot run on the UI thread
another thread that postsresults back on the UI thread
©SoftMoore Consulting
Class AsyncTask
• Class AsyncTask (package android.os) is a generic, abstract helper class for managing background operations that will eventually publish results back to the UI thread. It provides a convenient, easy-to-use alternative to manipulating threads and message handlers for background processing.
• Using class AsyncTask– create a subclass specifying types for three generic parameters– override callback methods as necessary
(must override method doInBackground(Params ...))
Slide 8
©SoftMoore Consulting
Generic Parameters for AsyncClass
public class AsyncTask<Params, Progress, Result>
• The three generic types used by an asynchronous task are as follows:– Params: the type of the parameters sent to the task upon
execution.– Progress: the type of the progress units published during the
background computation.– Result: the type of the result of the background computation.
• Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:private class MyTask extends AsyncTask<Void, Void, Void> { ... }
Slide 9
©SoftMoore Consulting
Four Callback Methods in AsyncTask
• onPreExecute() – invoked on the UI thread immediately before doInBackground().– normally used to setup the task, for instance by showing a
progress bar in the user interface
• doInBackground(Params...) – invoked on the background thread immediately after onPreExecute() finishes executing.– used to perform background computations that can take a long
time– parameters of the asynchronous task are passed to this step– result of the computation must be returned by this step– can also use publishProgress(Progress...) to publish
one or more units of progress to the UI thread
Slide 10
©SoftMoore Consulting
Four Callback Methods in AsyncTask(continued)
• onProgressUpdate(Progress...) – invoked on the UI thread after a call to publishProgress(Progress...). – used to display any form of progress in the user interface while
the background computation is still executing. For instance, it can be used to animate a progress bar or show logs in a text field.
• onPostExecute(Result) – invoked on the UI thread after doInBackground() finishes.– result of the background computation is passed to this step as a
parameter
Slide 11
©SoftMoore Consulting
Understanding How to Use AsyncTask
• Using generics you can specify the types of the parameters, the progress values, and the final value of the task.
• The method doInBackground() executes automatically on a worker thread.
• Methods onPreExecute(), onPostExecute(), and onProgressUpdate() are all invoked on the UI thread.
• The value returned by doInBackground() is sent to onPostExecute().
Slide 12
©SoftMoore Consulting
Understanding How to Use AsyncTask(continued)
• You can call publishProgress() at anytime in doInBackground() to execute onProgressUpdate() on the UI thread.
• You can cancel the task at any time, from any thread.
Slide 13
Important: An AsyncTask instance must be createdon the UI thread and can be executed only once; e.g.,create a new AsyncTask with every button click.
©SoftMoore Consulting
Outline for Using AsyncTask
// sample call; e.g., in an onClick() method for a buttonDownloadStockTask stockTask = new DownloadStockTask();stockTask.execute("GOOG");
// inner class defined within the activity classprivate class DownloadStockTask extends AsyncTask<String, Void, Stock> { protected Stock doInBackground(String... symbols) { ... // download stock information from internet } protected void onPostExecute(Stock stock) { ... } }
Slide 14
string passed to method doInBackbround()
returned value passed to method doOnPostExecute()
©SoftMoore Consulting
Example: Downloading a BitmapImage Using AsyncTask
// inner class defined within the onCreate() methodprivate class DownloadImageTask extends AsyncTask<String, Void, Bitmap> { protected Bitmap doInBackground(String... urls) { return loadImageFromNetwork(urls[0]); }
protected void onPostExecute(Bitmap result) { myImageView.setImageBitmap(result); } }
Slide 15
©SoftMoore Consulting
Example: Downloading a Bitmap Image(continued)
public void onClick(View v) { AsyncTask downloadTask = new DownloadImageTask(); downloadTask.execute("http://example.com/image.png"); }
Slide 16
©SoftMoore Consulting
Getting Stock Quotes from Yahoo
• You can use HTTP to obtain stock quotes from yahoo.com in a comma-separated values (csv) file format. The URL has the formhttp://finance.yahoo.com/d/quotes.csv?s= <stock symbols
separated by "+“>&f=<special tags>
• Selected special tags:– s : symbol – o : open– l : last trade with time – c : change and percent
change– w : 52-week range – n : name– r : P/E ratio – x : stock exchange
Slide 17
©SoftMoore Consulting
Example: Getting Stock Quotes from Yahoo
• Examplehttp://finance.yahoo.com/d/quotes.csv?s=GOOG&f=lcn
• Format for returned line:
Slide 18
last trade time/price change/percent name"3:21pm - <b>610.97</b>","+10.18 - +1.69%", "Google Inc."
Important: When accessing the internet, remember to add<uses-permission android:name="android.permission.INTERNET" />
before the application element in AndroidManifest.xml.
©SoftMoore Consulting Slide 19
Networking Application: Checking Stocks
public class Stock { private static final String QUOTE_FORMAT = "&f=lcwn";
private String symbol; private String lastTradePrice; private String lastTradeTime; private String change; private String range; private String name;
public Stock(String symbol) { this.symbol = symbol.toUpperCase(); }
... // continued on next several slides }
©SoftMoore Consulting Slide 20
Networking Application: Checking Stocks(continued)
public void load() throws MalformedURLException, IOException { URL url = new URL("http://finance.yahoo.com/d/quotes.csv?s=" + symbol + QUOTE_FORMAT); URLConnection connection = url.openConnection(); BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));
String line = in.readLine();
// consume any data remaining in the input stream while (in.readLine() != null) ;
in.close();
... // continued }
Note: This method is thepart of the applicationthat accesses the network.
©SoftMoore Consulting Slide 21
Networking Application: Checking Stocks(continued)
if (line != null && line.length() > 0) { // parse the line and remove quotes where necessary String[] values = line.split(","); change = values[1].substring(1, values[1].length() - 1); range = values[2].substring(1, values[2].length() - 1); name = values[3].substring(1, values[3].length() - 1);
// parse last trade time and price String lastTrade = values[0]; int start = 1; // skip opening quote int end = lastTrade.indexOf(" - "); lastTradeTime = lastTrade.substring(start, end);
start = lastTrade.indexOf(">") + 1; end = lastTrade.indexOf("<", start); lastTradePrice = lastTrade.substring(start, end); }
©SoftMoore Consulting
Relevant Links
• Processes and Threadshttp://developer.android.com/guide/components/processes-and-threads.html
• AsyncTaskhttp://developer.android.com/reference/android/os/AsyncTask.html
• Painless Threadinghttp://android-developers.blogspot.com/2009/05/painless-threading.html
• Using the Yahoo Finance API for CSVhttp://www.jarloo.com/yahoo_finance/
Slide 23