Post on 11-May-2015
transcript
Android MobAppDev
Asynchronous Tasks & Started Services
Vladimir Kulyukin
www.vkedco.blogspot.com
Outline
● Asynchronous Tasks● Started Services & Threads
Asynchronous Tasks
When to Use AsyncTask
● Asynchronous tasks (AsyncTask) allow developers to get long-running computations off the main UI thread
● AsyncTasks are best suited for long one-time computations (downloads, initializaitons, etc)
● If repeated computations are required, threads, background services and other tools in java.util.concurrent should be considered
AsyncTask<Param, Progress, Result>
● AsyncTask is defined by three generic parameters: Param, Progress, and Result
● Param, Progress, and Result must be legal Java data types
● Param is the input type● Progress is the progress type● Result is the output type
AsyncTask Execution
● An AsyncTask is executed in four stages, each of which is done in the corresponding overriden method given below
● These methods should not be invoked automatically
1) onPreExecute() 2) doInBackground(Param... input_params) 3) onProgressUpdate(Progress... progress_params) 4) onPostExecute(Result rslt)
AsyncTask.onPreExecute()
● onPreExecute() is executed on the main UI thread
● This method is used to do the setup and can complement the constructor
● If you application, for example, needs a progress bar, this method is the place to do it
AsyncTask.doInBackground()
● This method is invoked off the main UI thread
● This method is used to perform all background computation
● This method returns the Result type
AsyncTask.onProgressUpdate()
● The onProgressUpdate() method is invoked on the main UI thread
● The timing of execution is undefined in the documentation
● This method is executed while the background computation is still in progress
AsyncTask.onPostExecute()
● The onPostExecute() method is invoked on the main UI thread
● The method is executed after the background computation is done
● The result of the background computation is passed to this method
Implementation of AsyncTasks
● An implementation class must extend AsyncTask
● An implementation must, at the very least, implement doInBackground()
● Many implementations also implement onPostExecute()
AsyncTask Cancelation
● An AsyncTask can be canceled at any time by invoking cancel()
● You can check if an AsyncTask has been canceled via isCanceled()
● It is a good best practice to check if the task is canceled in doInBackground()
Threading & AsyncTasks
● An AsyncTask is created on the UI thread● An AsyncTask must do execute(Param...) on
the main UI thread● An AsyncTask guarantees that all callback
calls are synchronized
Cloud-Based Barcode Scanning Service
Problem
Implement an application that uses a started service to download randomly chosen barcode images from the cloud, upload them to a closed-based barcode reading service, and using notifications to display barcode strings on the status bar. When the user clicks on the notification in the notification tray, the nutrition label of the corresponding product is displayed.
Details are here
Sample Screenshots
Sample Images
Solution Outline
● The started service implements two asynchronous tasks: 1st task downloads images from the cloud, 2nd task uploads images to the cloud
● The started service implements a worker thread that uses both asynchronous tasks to manipulate images
DownloadImageTask private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
File mFile = null;
public DownloadImageTask(File fn) { mFile = fn; }
protected Bitmap doInBackground(String... urls) {
Bitmap map = null;
for (String url : urls) { map = downloadImage(url); }
if (!mFile.exists()) { this.saveBitmapToFile(map, mFile); }
return map;
}
…
}
Details are here
DownloadImageTask
private class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
File mFile = null;
public DownloadImageTask(File fn) { mFile = fn; }
protected void onPostExecute(Bitmap result) {
if (mDownloadedBitmap != null) {
mDownloadedBitmap.recycle();
mDownloadedBitmap = null;
}
mDownloadedBitmap = result;
}
Details are here
UploadImageTask
private class UploadImageTask extends AsyncTask<File, Void, String> {
protected String doInBackground(File... urls) {
String nl = "";
for (File url : urls) { nl = uploadFile(url); }
return nl;
}
...
}
Details are here
UploadImageTask private class UploadImageTask extends AsyncTask<File, Void, String> {
protected void onPostExecute(String result) {
String barcode = getBarcode(result);
File nlTxtFile =
new File(Environment.getExternalStorageDirectory() + "/" + barcode + ".txt");
if (!nlTxtFile.exists()) {
PrintWriter pw;
try {
pw = new PrintWriter(nlTxtFile); pw.write(result);
pw.flush(); pw.close(); pw = null;
} catch (FileNotFoundException e) { e.printStackTrace(); }
}
ImageUploadService.this.postBarcodeNotification(barcode);
}
}
Details are here
Service Worker Thread
int file_num = mRandomNumberGenerator.nextInt(9);
File imageFile = new File(
Environment.getExternalStorageDirectory() + "/" + Integer.toString(file_num) + ".jpg");
// Create and execute a DownloadImageTask
DownloadImageTask downTask = new DownloadImageTask(imageFile);
downTask.execute(new String[] { BARCODE_IMAGE_URLS[file_num] });
// Create and execute an UploadImageTask
UploadImageTask upTask = new UploadImageTask();
upTask.execute(new File[] { imageFile });
Details are here