Through the study of the previous articles, we have a certain understanding of Android multi-threaded communication. So in this article, let's talk about the built-in asynchronous task class AsyncTask of the Android system. Using AsyncTask allows us to only focus on time-consuming operations and UI updating operations in sub-threads. It is simpler to use than Handler. Of course, it is only for some simple operations, such as network operations, image loading, data acquisition, and so on.
basic introduction
First of all, AsyncTask is an abstract class. Generally, when we use it, we will define a subclass of it and override its methods to use it. Let's look at the class definition first:
/**
* Params:启动任务传入参数
* Progress:任务执行进度值
* Result:异步任务完成返回值
*/
public abstract class AsyncTask<Params, Progress, Result> {
}
We need to pass in three generics, which are parameters, progress and return values. The most important methods are:
/**
* 主线程中执行,调用execute方法后立即执行
*/
@MainThread
protected void onPreExecute() {
}
/**
* 工作线程中执行,会在执行完onPreExecute后执行方法
* @param Params 接受参数
* @return 返回结果,传递给onPostExecute
*/
@WorkerThread
protected abstract Result doInBackground(Params... params);
/**
* 主线程执行,在手动调用publishProgress后被自动调用
* @param values 异步任务进度
*/
@MainThread
protected void onProgressUpdate(Progress... values) {
}
/**
* 主线程执行,工作任务完成后调用该方法
* @param result 返回结果
*/
@MainThread
protected void onPostExecute(Result result) {
}
The execution order is like this. After the asynchronous task calls the execute
method, it will immediately execute the onPreExecute
method in the UI thread. Generally, we will perform some initialization operations in this, and then call the doInBackground
method in the opened child thread to perform time-consuming operations. If the method is manually called during the time operation publishProgress
, the system will automatically call the onProgressUpdate
method to update the progress. After the asynchronous task is executed, it will be called in the UI thread and doInBackground
the return value will be passed to the onPostExecute
method as a parameter. At this point, the asynchronous task is completed.
Example of use
Let's use a practical example to demonstrate the use of AsyncTask:
class DownloadImageTask extends AsyncTask<String,Void,Bitmap> {
/**
* 主线程中执行,调用execute方法后立即执行
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
pbLoading.setVisibility(View.VISIBLE);
ivContainer.setImageBitmap(null);
}
/**
* 工作线程中执行,会在执行完onPreExecute后执行方法
* @param strings 接受参数
* @return 返回结果,传递给onPostExecute
*/
@Override
protected Bitmap doInBackground(String... strings) {
//下载图片,返回bitmap对象
String url = strings[0];
URLConnection connection;
InputStream inputStream;
Bitmap result = null;
try {
connection = new URL(url).openConnection();
inputStream = connection.getInputStream();
BufferedInputStream bis = new BufferedInputStream(inputStream);
result = BitmapFactory.decodeStream(bis);
bis.close();
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
return result;
}
/**
* 主线程执行,在手动调用publishProgress后被自动调用
* @param values 异步任务进度
*/
@Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
/**
* 主线程执行,工作任务完成后调用该方法
* @param bitmap 返回结果
*/
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
pbLoading.setVisibility(View.GONE);
ivContainer.setImageBitmap(bitmap);
}
}
A very simple asynchronous task for downloading pictures, and the calling method is also very simple:
protected void loadImage(View view) {
asyncTask = new DownloadImageTask();
asyncTask.execute(IMAGE_URL);//可以接受多个参数
}
Here, we must pay attention to the definition type when using AsyncTask. Do not write AsyncTask directly, but directly use the type of its subclass. Otherwise, a ClassCastException will be caused due to the problem of generics.
To summarize the caveats of AsyncTask :
AsyncTask can only be initialized and executed in the main thread
The four important methods of AsyncTask are not called by the programmer, and
doInBackground
they are all executed in the main thread except for the child thread.The way to cancel the AsyncTask is to call the
cancle()
method and use theisCanceled
judgment during the execution of the asynchronous task. If it is false, the task is terminated.The internal thread pool of AsyncTask uses the synchronous thread pool by default, that is, after a task is completed, the next task is executed. To use the asynchronous thread pool, use
asynct.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, 0);
Finally, the github address ~
my personal blog , welcome to visit~