Android asynctask usage and source code analysis

overview

In Android, we need to perform some time-consuming operations, which will be carried out in the sub thread. After the sub thread operation is completed, we can send a message through the handler to inform the UI of some update operations (for specific use and principle, see the message mechanism of Android - the working process of handler). Of course, in order to simplify our operations, we have provided the asynctask class after Android 1.5, which can return the results of the sub thread processing to the UI thread, and then we can carry out a series of UI operations according to these results.

How to use asynctask

In fact, asynctask encapsulates the handler and thread pool. It is a lightweight asynchronous task class, and its background tasks are carried out in the thread pool. Then we can pass the result of task execution to the main thread, and then we can operate the UI in the main thread. Asynctask is an abstract generic class, so we create a subclass to implement the abstract methods in asynctask. Asynctask provides three generic parameters. Let's take a look at these three generic parameters. 1. Params: the parameter passed when executing asynctask, which is used in the background thread. 2. Progress: type of background task execution progress. 3. Result: type of result returned after background task execution is completed. When we don't need to use the above three generic parameters, we can use void instead. Similar to the activity life cycle, asynctask also provides us with some methods. We complete the whole asynchronous task by rewriting these methods. We mainly use the following four methods: 1. Onpreexecute(): this method is executed before the asynchronous task works. It is mainly used for the initialization of some parameters or UI. 2. Doinbackground (params... Params): this method is executed in the process pool. The params parameter represents the parameters entered during asynchronous tasks. In this method, we notify the task progress through publishprogress. 3. Onprogressupdate (Progress... Values): this method will be called when the progress of background tasks changes. We can display the UI progress in this method. The values parameter indicates the task progress. 4. Postresult (result result): executed after the asynchronous task is completed. The result parameter is the result returned after the asynchronous task is executed. Of the above four methods, only doinbackground runs in the child thread, and the other three methods run in the main thread. Where... Indicates that the number of parameters is uncertain. It is an array type parameter. Let's write an example to see the usage of asynctask. Here we will download two files from the network with a download function. Let's take a look at the effect demonstration first.

Effect demonstration

code analysis

Because of the download task we do, first we have to add access to the network and some SD card related permissions.

Let's take a look at the activity code.

There are several points we need to pay attention to in the above code. 1. The execute method in asynctask must be executed in the main thread. 2. Each asynctask object can execute the execute method only once. 3. When our activity is destroyed, we need to cancel. The Boolean parameter mayinterruptifrunning indicates whether to interrupt the background task. The final layout code is very simple, just a button.

Here's another point to explain. Because asynctask has been modified many times in different Android versions, when we execute multiple execute methods through multiple asynctask objects, whether their execution order is serial or parallel varies according to different versions of the system, so we won't analyze it in detail here.

Asynctask source code analysis

Here, we use the asynctask source code in Android 6.0 for analysis. There will be some differences in the asynctask code of different systems. After creating an asynctask object, we can execute the whole task through the execute method. Let's first look at the code in the execute method.

You can see that the code in the execute method is so simple that it just executes the executeonexecutor method and returns the asynctask object. Let's take a look at the executeonexecutor method.

In this method, we first judge the execution status of asynctask. If the asynctask is executing a task or the task has been completed by a confidant, an exception will be thrown to us, which explains that each asynctask object can only execute the execute method once. The onpreexecute method is executed immediately after the current task state is changed to running. This also shows that among the four methods we have rewritten above, the onpreexecute method points to first. Let's take a look at the two global variables mworker and mfuture. Mfuture is a futuretask object, while mworker is a workerrunnable object. Workerrunnable is an abstract internal class in asynctask that implements the callable interface. Only one params [] is defined in workerrunnable.

Mfuture and mworker are initialized in the constructor of asynctask. Let's take a look at the construction method of asynctask.

Here, first create a workerrunnable object mworker, and implement the call method of the callable interface. The contents of this call aspect will be described in detail later. Then we create a futuretask object mfuture through mworker, and override the done method. When we call the cancel method in asynctask, the done method will be called in futuretask. After introducing mworker and mfuture here, let's go back to the executeonexecutor method. Here we initialize mparms in mworker through the params parameter we passed in. The following exec is the sdefaultexector passed in the execute and executes the execute method of sdefaultexector. Let's take another look at the sdefaultexecution object.

Here, I will first introduce this code as a whole. The main function of this code is to create two thread pools, serialexecutor and thread_ POOL_ EXECUTOR。 The serialexecutor thread pool is used to queue tasks, while thread_ POOL_ Executor is used to execute tasks. Sdefaultexecution is the serialexecutor thread pool. Let's go into the serialexecutor code and take a look at the contents. The parameter runnable in the execute method in the serialexecutor is the mfuture we passed in. A runnable object is created in the execute method and the queue is inserted at the end of the object. If this is the first time to perform the task. Active must be null. In this case, the schedulenext method is called to take out the runnable object from the queue and pass thread_ POOL_ The executor thread pool executes tasks. We can see that in the run method of runnable in the queue, the run method in mfuture is executed first, and then the schedulenext method will be called to take runnable from the queue for execution until all runnable are executed. Let's take a look at how to execute this runnable in the online city. As can be seen from the above code, the core part of executing runnable in the online city is to execute the run method of mfuture. Let's take a look at the run method in mfuture.

The callable object in this method is the mworker object in our asynctask. It is also the call method in mworker to complete some time-consuming tasks, so we can think that the doinbackground I rewritten should be executed in this call method. Now go back to the construction method of asynctask and take a look at the call method in this mworker.

Here we can clearly see that it executes our overridden doinbackground method and passes the returned result to the postresult method. Let's take a look at the postresult method.

Yes, in the postresult method, that is, after the task processing of our sub thread is completed, the message is sent to the main thread through a handler object and handed over to the main thread for processing. The asynctask result object stores the results returned by the child thread and the current asynctask object. Let's take a look at this and what is handled in the handler.

You can see that two types of messages will be accepted in the handlemessage of this handler. In message_ POST_ The progress message mainly sends the execution progress of the child thread to the main thread through the publishprogress method, and updates the display of the progress bar through the onprogressupdate method. In message_ POST_ In the result message, the finish method is called through the current asynctask object. Let's take a look at the finish method.

At this time, we can see that if we cancel the asynctask, we will not execute the onpostexecute method, but the oncancelled method. Therefore, we can override the oncancelled method to perform some operations that we need to handle when canceling. Of course, if the asynctask is not cancelled, the onpostexecute method will be executed. Here, the whole asynctask task is completed.

summary

As can be seen from the above serialexecutor thread pool, when multiple asynchronous tasks are executed at the same time, their execution order is serial and will be executed once according to the order of task creation. If we want multiple tasks to execute concurrently, we can set the thread pool to thread through the setdefaultexecutor method in asynctask_ POOL_ Just execute. I have to mention the differences between different versions of asynctask. In Android 1.6, asynctask uses serial execution of tasks. In Android 1.6, it uses thread pool to process parallel tasks, while it uses serialexecutor thread pool to process tasks after 3.0. Before Android 4.1, the asynctask class must be in the main thread, but it is automatically completed by the system in later versions. In Android 5.0, the init method of asynctask will be executed in the main method of activitythread, and the init method will be deleted in Android 6.0. Therefore, when using this asynctask, if it is suitable for more system versions, you should pay attention to it.

Source code download: https://github.com/lijiangdong/asynctask-example

The above is the whole content of this article. I hope it will be helpful to your study, and I hope you can support programming tips.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>