Android Development Notes: multi-threaded AsyncTask

Source: Internet
Author: User

Understanding AsyncTask
AsyncTask is a class added by the Android 1.5 Cubake for asynchronous operations. Previously, Thread in the Java SE library can only be used to implement multi-Thread Asynchronization. AsyncTask is the asynchronous tool of the Android platform, integrates the features of the Android platform to make asynchronous operations more secure, convenient, and practical. Essentially, it is also an encapsulation of the Thread in the Java SE library, with platform-related features added, so AsyncTask is strongly recommended for all multi‑thread Asynchronization, because it considers that, it also integrates the features of the Android platform, making it more secure and efficient.
AsyncTask can easily execute asynchronous operations (doInBackground) and communicate with the main thread. It has good encapsulation and can cancel operations (cancel ()). About the use of AsyncTask, the document is very clear, the following directly on the instance.
Instance
This instance uses AsyncTask to download images from the network and display the progress. After the image is downloaded, the UI is updated. Copy codeThe Code is as follows: package com. hilton. javastiveandroid. concurrent;
Import java. io. IOException;
Import java. io. InputStream;
Import java. io. OutputStream;
Import java.net. HttpURLConnection;
Import java.net. MalformedURLException;
Import java.net. URL;
Import android. app. Activity;
Import android. content. Context;
Import android. graphics. Bitmap;
Import android. graphics. BitmapFactory;
Import android. OS. AsyncTask;
Import android. OS. Bundle;
Import android. OS. SystemClock;
Import android. view. View;
Import android. widget. Button;
Import android. widget. ImageView;
Import android. widget. ProgressBar;
Import com. hilton. inclutiveandroid. R;
/*
* AsyncTask cannot be reused, I. e. if you have executed one AsyncTask, you must discard it, you cannot execute it again.
* If you try to execute an executed AsyncTask, you will get "java. lang. IllegalStateException: Cannot execute task: the task is already running"
* In this demo, if you click "get the image" button twice at any time, you will receive "IllegalStateException ".
* About cancellation:
* You can call AsyncTask # cancel () at any time during AsyncTask executing, but the result is onPostExecute () is not called after
* DoInBackground () finishes, which means doInBackground () is not stopped. AsyncTask # isCancelled () returns true after cancel () getting
* Called, so if you want to really cancel the task, I. e. stop doInBackground (), you must check the return value of isCancelled () in
* DoInBackground, when there are loops in doInBackground in particle.
* This is the same to Java threading, in which is no valid tive way to stop a running thread, only way to do is set a flag to thread, and check
* The flag every time in Thread # run (), if flag is set, run () aborts.
*/
Public class AsyncTaskDemoActivity extends Activity {
Private static final String ImageUrl = "http://i1.cqnews.net/sports/attachement/jpg/site82/2011-10-01/2960950278670008721.jpg ";
Private ProgressBar mProgressBar;
Private ImageView mImageView;
Private Button mGetImage;
Private Button mAbort;

@ Override
Public void onCreate (Bundle icicle ){
Super. onCreate (icicle );
SetContentView (R. layout. async_task_demo_activity );
MProgressBar = (ProgressBar) findViewById (R. id. async_task_progress );
MImageView = (ImageView) findViewById (R. id. async_task_displayer );
Final ImageLoader loader = new ImageLoader ();
MGetImage = (Button) findViewById (R. id. async_task_get_image );
MGetImage. setOnClickListener (new View. OnClickListener (){
Public void onClick (View v ){
Loader.exe cute (ImageUrl );
}
});
MAbort = (Button) findViewById (R. id. asyc_task_abort );
MAbort. setOnClickListener (new View. OnClickListener (){
Public void onClick (View v ){
Loader. cancel (true );
}
});
MAbort. setEnabled (false );
}

Private class ImageLoader extends AsyncTask <String, Integer, Bitmap> {
Private static final String TAG = "ImageLoader ";
@ Override
Protected void onPreExecute (){
// Initialize progress and image
MGetImage. setEnabled (false );
MAbort. setEnabled (true );
MProgressBar. setVisibility (View. VISIBLE );
MProgressBar. setProgress (0 );
MImageView. setImageResource (R. drawable. icon );
}

@ Override
Protected Bitmap doInBackground (String... url ){
/*
* Fucking ridiculous thing happened here, to use any Internet connections, either via HttpURLConnection
* Or HttpClient, you must declare INTERNET permission in AndroidManifest. xml. Otherwise you will get
* "UnknownHostException" when connecting or other TCP/IP/http exceptions rather than "SecurityException"
* Which tells you need to declare INTERNET permission.
*/
Try {
URL u;
HttpURLConnection conn = null;
InputStream in = null;
OutputStream out = null;
Final String filename = "local_temp_image ";
Try {
U = new URL (url [0]);
Conn = (HttpURLConnection) u. openConnection ();
Conn. setDoInput (true );
Conn. setDoOutput (false );
Conn. setConnectTimeout (20*1000 );
In = conn. getInputStream ();
Out = openFileOutput (filename, Context. MODE_PRIVATE );
Byte [] buf = new byte [1, 8196];
Int seg = 0;
Final long total = conn. getContentLength ();
Long current = 0;
/*
* Without checking isCancelled (), the loop continues until reading whole image done, I. e. the progress
* Continues go up to 100. But onPostExecute () will not be called.
* By checking isCancelled (), we can stop immediately, I. e. progress stops immediately when cancel () is called.
*/
While (! IsCancelled () & (seg = in. read (buf ))! =-1 ){
Out. write (buf, 0, seg );
Current + = seg;
Int progress = (int) (float) current/(float) total * 100f );
PublishProgress (progress );
SystemClock. sleep (1000 );
}
} Finally {
If (conn! = Null ){
Conn. disconnect ();
}
If (in! = Null ){
In. close ();
}
If (out! = Null ){
Out. close ();
}
}
Return BitmapFactory. decodeFile (getFileStreamPath (filename). getAbsolutePath ());
} Catch (MalformedURLException e ){
E. printStackTrace ();
} Catch (IOException e ){
E. printStackTrace ();
}
Return null;
}

@ Override
Protected void onProgressUpdate (Integer... progress ){
MProgressBar. setProgress (progress [0]);
}

@ Override
Protected void onPostExecute (Bitmap image ){
If (image! = Null ){
MImageView. setImageBitmap (image );
}
MProgressBar. setProgress (100 );
MProgressBar. setVisibility (View. GONE );
MAbort. setEnabled (false );
}
}
}

Running result

The order is before, during, and after the download.
Summary
Reading the document and the example about how to use it is enough. The following describes the precautions for use:
1. the AsyncTask object Cannot be used repeatedly. That is to say, an AsyncTask object can only execute () once. Otherwise, an exception will be thrown "java. lang. IllegalStateException: Cannot execute task: the task is already running"

2. Check the returned value of isCancelled () in doInBackground (). If your asynchronous task can be canceled.
Cancel () only sets a flag for the AsyncTask object. After cancel () is called, only the flag of the AsyncTask object has changed, and after doInBackground () is executed, onPostExecute () will not be called back, And doInBackground () and onProgressUpdate () will continue to be executed until doInBackground () ends. Therefore, you must constantly check the isCancellled () Return Value in doInBackground (). When it returns true, the execution is stopped, especially when there is a loop. In the above example, if the isCancelled () Check of the read data is removed, the image will still be downloaded and the progress will keep going, but the final picture will not be placed on the UI (because onPostExecute () not called back )!

The reason here is actually very understandable. Think about the Java SE Thread, there is no way to directly Cacncel it out, and the cancellation of those threads is nothing more than setting a flag for the Thread, and then in the run () method.

3. if you want to use the network in an application, do not forget to declare INTERNET permissions in AndroidManifest; otherwise, a strange exception message will be reported, such as the preceding example, if you remove INTERNET permissions, an "UnknownHostException" is thrown ". At the beginning, I was very confused because the simulator was able to access the Internet normally. After Google found out that the simulator had no permissions, but the question was still not resolved. Since no network permission was declared, why don't I directly prompt that I have no network permissions?

Comparison of Java SE Thread
Thread is a very primitive class. It has only one run () method. once started, it cannot be stopped. It is only suitable for a very independent asynchronous task, that is, it does not need to interact with the main Thread, in other cases, for example, to cancel or interact with the main thread, you must add additional code to implement it and pay attention to synchronization issues.
AsyncTask is encapsulated and can be used directly. If you only execute an independent asynchronous task, you can only implement doInBackground ().
Therefore, when there is a very independent task, you can consider using Thread. In other cases, use AsyncTask as much as possible.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.