In the process of Android application development, we need to always pay attention to ensure the stability of the application and the timely response of UI operations, unstable or poor response will bring bad user experience.
So why AsyncTask?
A separate process is started when an Android application starts running, and by default all application operations are performed in this process. An Android application has only one process by default, but there can be multiple threads in a process.
One of these threads is called a UI Thread (also called a Main Thread), and all threads other than the UI Thread are called Worker threads. The UI thread is mainly responsible for controlling the display, update and interaction of the UI interface. Therefore, the operation latency in the UI thread is as short as possible (smooth). Putting time-consuming operations (network requests, database operations, logical calculations, and so on) into a separate thread prevents the main thread from blocking. So how do you implement this asynchronous approach?
Android provides a lightweight asynchronous task class called AsyncTask. The class realize the asynchronous operation, and provides the interface feedback current asynchronous execution result and progress, these interfaces are run directly in the main thread (such as onPostExecute, onPreExecute, etc.).
AsyncTask: AndroidAPI: AsyncTask
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
// Escape early if cancel() is called
if (isCancelled()) break;
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes"); }} See moreCopy the code
Once created, a task is executed very simply:
new DownloadFilesTask().execute(url1, url2, url3);
Copy the code
The three types used by an asynchronous task are the following:
-
Params, the type of the parameters sent to the task upon execution.
// The type of argument sent to the task at execution time.
2.Progress, the type of the progress units published during the background computation.
// Progress, the progress unit type in the background calculation process, which implements the progress bar, where the publishProgress() parameter corresponds to the onProgressUpdate() parameter.
3.Result, the type of the result of the background computation.
// This result is the result returned by doInBackground, the method received is onPostExecute() and the result argument is the returned argument
Not all types are always used by an asynchronous task. To mark a type as unused, simply use the type Void:
// Asynchronous tasks always use not all types. To mark a type as unused, simply use the type Void:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }1. OnPreExecute () is called on the UI thread before the task is executed. This step is typically used to set up tasks, for example by displaying a progress bar in the user interface.Copy the code
The 4 steps
When an asynchronous task is executed, the task goes through 4 steps:
1.onPreExecute(), invoked on the UI thread before the task is executed. This step is normally used to setup the task, for instance by showing a progress bar in the user interface.
2.doInBackground(Params…) . invoked on the background thread immediately after onPreExecute() finishes executing. This step is used to perform background computation that can take a long time. The parameters of the asynchronous task are passed to this step. The result of the computation must be returned by this step and will be passed back to the last step. This step can also use publishProgress(Progress…) to publish one or more units of progress. These values are published on the UI thread, in the onProgressUpdate(Progress…) step.
3.onProgressUpdate(Progress…) , invoked on the UI thread after a call to publishProgress(Progress…) . The timing of the execution is undefined. This method is 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.
4.onPostExecute(Result), invoked on the UI thread after the background computation finishes. The result of the background computation is passed to this step as a parameter.
When an asynchronous task is executed, the task goes through four steps:
1. OnPreExecute () is called on the UI thread before the task is executed. This step is typically used to set up tasks, for example by displaying a progress bar in the user interface.
2. DoInBackground (Params…) , called on the background thread immediately after onPreExecute () completes execution. This step is used to perform background calculations that may take a long time. Parameters for asynchronous tasks are passed to this step. The result of the calculation must be returned from this step and back to the last step. This step can also use publishProgress (Progress…) Publish one or more units of progress. These values are on the UI thread, in onProgressUpdate (Progress…) Step release.
3. OnProgressUpdate (Progress…) , calling publishProgress (Progress…) Call it on the UI thread. The execution time is not defined. This method is used to display any form of progress in the user interface while the background calculation is still executing. For example, it can be used to animate progress bars or display logs in text fields.
4. OnPostExecute (Result) is invoked on the UI thread after the background calculation is complete. The result of the background calculation is passed to the step as a parameter.
Cancel the task
The task can be cancelled at any time by calling Cancel (Boolean). Calling this method causes subsequent calls to isCancelled () to return true. After calling this method, onCancelled (Object) instead of onPostExecute (Object) will be called after doInBackground (Object []) returns. To ensure that tasks are cancelled as quickly as possible, you should always periodically check the return value of isCancelled () from doInBackground (Object []), if possible.
Thread rules
There are some threading rules that must be followed by this class to work properly:
The AsyncTask class must be loaded on the UI thread. Automatically execute jelly_beans.
The task instance must be created on the UI thread.
Execute (Params…) must be called on the UI thread. .
Do not manually call onPreExecute (), onPostExecute (Result), doInBackground (Params…) , onProgressUpdate (Progress…) .
This task can only be executed once (an exception will be thrown if it is attempted a second time).
Observability of memory
AsyncTask guarantees that all callback calls are synchronous, making the following operations safe without explicit synchronization.
Set the member field in the constructor or onPreExecute () and in doInBackground (Params…) Reference them in.
In doInBackground (Params…) Set the member field in onProgressUpdate (Progress…) And onPostExecute (Result) reference them.
Execution order
When first introduced, AsyncTasks are executed serially on a single background thread. Starting with DONUT, this was changed to a thread pool that allows multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors associated with parallel execution.
If you really want to parallel execution, can use THREAD_POOL_EXECUTOR call executeOnExecutor (Java. Util. Concurrent. The Executor, Object []).