The difference between using thread thread and asynctask asynchronous task in Android

Recently, when I talked with several friends about the network download problem in Android development, I talked about the bug that will be generated when starting the download thread with thread. In fact, it is really a low practice to directly start the download task with sub thread. What is the reason, and what is the practice on a larger scale? So use this blog post to analyze and record it in detail.

1、 Concept introduction

Thread means that there can be multiple execution paths in a program running by CPU. The running program is called a process, and this execution path is called a thread (if you don't understand these two terms, you can refer to the books on the operating system). Multithreading in Java means that multiple threads can be executed synchronously within a period, which can improve the running efficiency of code. In Java, a process is allowed to have multiple threads, which can be unlimited, but there must be one thread, that is, the main thread of the current process.

It must be understood that thread is an underlying class under the Java language, and Android is a system that uses and encapsulates the Java language, so asynctask in Android only uses the concept of Java multithreading and optimizes an abstract class after encapsulation. Therefore, thread and asynctask are completely two different levels of concepts, not a simple replacement.

Besides, asynctask is designed to be a helper class around {@ link thread} and {@ link handler} and does not construct a generic threading framework. Asynctasks should be used for short operations (a feed seconds at the most.) If you need to keep threads running for long periods of time, it is highly recommended that you use the various APIs ", you don't need to paste the following unimportant ones, which can be seen when asynchronous tasks operate for a long time. Because the running of each app in Android is regarded as a process, and the main thread in this process is the UI thread, that is, the thread that we can see the interface when we open an app. For time-consuming operations such as downloading, if placed in the UI thread for execution, the UI thread will be overloaded and the anr application will not respond. Therefore, the asynctask class is created to perform some time-consuming non UI update operations.

Through the above introduction, it is easy to think that asynctask uses the multithreading technology in Java, but it is not a simple thread. We can see the source code comparison on how to implement asynchronous tasks.

The thread class is under the java.lang package, so there is no need to import another package for its use, and the thread is a class that implements the runnable interface, that is, it can be instantiated; Since thread is the underlying code, the specific source code will not be analyzed, so we mainly talk about how asynctask uses thread to implement asynchronous tasks.

Asynctask class is an abstract class under android.os package, which must be imported before use. Asynctask uses the thread factory to create new threads to execute asynchronous tasks in the background. Previously, we said that there is a UI thread as the main thread in Android, so the re created threads are sub threads. What the newly created sub threads do depends on our wishes.

2、 Download analysis:

After introducing the comparison between the two classes for half a day, I feel it's faster to go directly to the demo. In the following, I realize the download by opening sub thread and asynchronous respectively, and briefly analyze the CPU execution sequence under these two methods.

1. Open the child thread in the current activity to perform download

(1) Create download sub thread:

(2) Execute the tasks after downloading in the handler:

(3) Start the current download thread where you want to download:

1 myThread.start();

It only needs the above three steps to complete the download network request easily. Does it look very simple? The problem is that the download task is executed in the child thread of myThread. If the user performs page Jump while the download task is still executing, that is, the UI thread of the current activity has been destroyed, but the child thread of myThread has not been destroyed. Then after myThread executes the download () method of download task, He then calls the handler to send information to execute the data operation. The handler executing the data operation is defined in the current activity. With the destruction of the current activity, the current handler is destroyed. In this way, the handler executing the data cannot be called in myThread, so he must report nullpointexception. Therefore, it is not safe to use sub threads for download tasks.

2. Use asynctask to perform the download task

Therefore, in Android, the native asynctask can be used for time-consuming operations such as downloading network requests. The specific method is to create a download task, inherit the asynctask abstract class, and rewrite the doinbackground () in the class. This method is executed in the child program to be downloaded. Click the source code of asynctask, and we can see it in doinbackground () There is a comment @ workthread in front of this method. It can be thought that this method is executed in the working thread. Is there a method executed in the main thread? Of course, there are. We will also see that there are several methods. There are no execution statements in their method bodies, indicating that they can be overridden by subclasses. Construction methods, execute(), onpreexecute(), oncancelled(), etc., are all executed in mainthread.

Then, some students may want to ask a question. In this way, the task to be downloaded is still executed in the sub thread. Does the critical event mentioned above happen again, and there will be no null pointer exception after the sub thread is downloaded?

Of course, it is certain that the above bugs will never occur when using asynctask. Why? We then analyze.

In addition to the doinbackground () currently downloaded, the only method executed in the worker thread is publishprogress (), and doinbackground () is an abstract method. Therefore, if you want to know what the worker thread has, you can only find clues from publicprogress (). We know that this method is used when publishing progress. Here is the source code of this method,

Obviously, this gethandler () is to obtain the handler object in the current asynctask class, that is, the progress published in the working thread will send the information to the handler of the current asynctask for processing. No matter how the progress is published in the working thread, we just need to see how the received information is processed in the current asynctask.

This method obviously returns an internalhandler object when the shandler is not empty. The whole process locks the asynctask, and locking here is the key. After all, we should ensure the security when sending messages. After obtaining an internalhandler object, the whole asynctask is locked. Then let's go to see what this internalhandler is for.

First of all, we can confirm that this is a subclass that inherits the handler class. Only the following lines of code are executed in his handlermessage(). Here we should be about to find the root of our problem.

It is found that there are only two types of information sent here: message_ POST_ Progress is exactly the type of information sent in the method publicprogress() that just published the progress. Then the first message_ POST_ Result, it's not hard to imagine that this is the type of information sent after doinbackground() is executed in the working thread, and people have commented that "there is only one result" and "there is only one result". After we get this information, that is, after our download task is executed, we will call the next method. In fact, we don't have to look down, Because the executed method is the finish () method of the current asynctask itself. This shows that after the doinbackground () of the working thread is normally executed, finish () is executed in the main thread, so our thinking is straightened out.

Well, maybe after reading the above code and my analysis, some students feel even more confused. It seems that there is no explanation for the problem of Midway jump here. Then you have to think about it carefully. What is the root cause of null pointer exception in the midway jump after directly starting the sub thread download? The null pointer exception is caused by the fact that the handler object in the main thread cannot be used in the child thread. So how does our asynchronous task asynctask solve the problem of sending information?

When using handler to send information, the system will first call gethandler () to obtain an internalhandler object. If it is not created before, use the previous one if it is available. Moreover, because the current asynchronous task asynctask is locked in the whole process, other threads cannot be used. Similarly, it cannot be destroyed at will in the main thread using asynctask. In this way, the returned handler can be used to send information, and the null pointer exception can be crossed smoothly.

3、 Summary

This explanation, I believe that the students who are still confused should understand a little. Next, I will make a brief summary.

Asynctask is an asynchronous task that performs time-consuming operations other than UI interface update tasks. The UI interface is updated in the main thread, that is, the UI thread. In this asynchronous task, a worker thread is started to perform time-consuming operations. The execution sequence of the worker thread and the UI thread is not synchronized, that is, only after the download in the worker thread is completed, the onpostexecute() in the UI thread will be called to perform subsequent UI operations, so as to realize asynchronous download. If the worker thread sends the end of download information after the UI thread is destroyed, because the worker thread is bound to asynctask during reuse, it will also be destroyed with the destruction of the current asynctask. Subsequent download operations will not be performed, and naturally the end of download information will not be sent.

Simply start the sub thread to download, and the sub thread and UI thread only maintain a simple synchronization relationship, so it is unsafe to simply perform the download time-consuming operation in the sub thread. Facts have proved that although multithreading in Java is a good mechanism, we should pay attention to its side effects and learn to use its encapsulated classes and methods.

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
分享
二维码
< <上一篇
下一篇>>