The difference between using thread threads in Android and Asynctask asynchronous tasks

Source: Internet
Author: User
<span id="Label3"></p><p><p>Recently with a few friends on the Android development in the network download problem, talking about using thread to open the download thread when the bug, in fact, the direct use of sub-thread to open the download task is indeed very low practice, then what is the reason, and relatively tall on the way? So use this blog detailed analysis of the Record.</p></p><p><p>first, Concept Introduction</p></p><p><p>Thread refers to a program that runs on the CPU and can have multiple execution paths. A program that runs is called a process, and this execution path is called a thread (if a classmate who doesn't understand the two nouns can refer to a book on the operating system). Multithreading in Java means that multiple threads can be executed synchronously over a period of time, which can improve the efficiency of the code, allowing a process to have more than one thread in java, but there must be one thread, that is, the current Process's main thread.</p></p><p><p>It must be understood that thread is an underlying class in the Java language, and that Android is a system that uses and encapsulates the Java language, so asynctask in Android simply uses the multithreaded concept of Java and optimizes an abstract class after Encapsulation. So thread and Asynctask are completely two different levels of concepts, not simple replacements.</p></p><p><p>Say Asynctask asynchronous task, This class is used in android, when writing this class has been clearly stated, "asynctask is designed to be a helper class around {@link Thread} and {@li NK Handler} and does not constitute a generic threading Framework. Asynctasks should ideally is used for short operations (a few seconds at the Most.) If you need to keep threads running for long periods of time, it's highly recommended you use the various APIs ", it doesn't matter what's behind it. pasted, you can see that the asynchronous task is used for a long time Operation. Because every app runs in Android as a process, the main thread in the process is the UI thread, which is the thread that we can see when we open an app. and, like downloading this time-consuming operation, if put into the UI thread executes, it will cause the UI thread to be too heavy to produce the ANR application unresponsive exception, so the Asynctask class is created to dedicate some time-consuming non-ui update operations.</p></p><p><p>Through the above introduction, it is easy to think that Asynctask is using the multithreading technology in java, but he is not a simple thread, specifically how to implement asynchronous tasks, we can see the source Comparison.</p></p><p><p><span style="line-height: 1.5;"></span> The <span style="line-height: 1.5;">thread class is under the Java.lang package, so his use does not need additional guidance, and thread is to implement the Runnable interface class, that is, he can instantiate; because thread is the underlying code, the specific source is no longer analyzed, so the main talk about as Ynctask How to implement asynchronous tasks with Thread. </span></p></p><p><p>the <span style="line-height: 1.5;">Asynctask class is an abstract class under the Android.os package, which must be guided before it is Used. Asynctask is to use the thread factory to create a new thread to perform asynchronous tasks in the background,</span> <span style="line-height: 1.5;">before we say that there is a UI thread in Android as the main thread, then the threads that are created are child threads, and what the newly created sub-threads do, Depends on our Wishes. </span></p></p><p><p><span style="line-height: 1.5;">second, Download Analysis:</span></p></p><p><p><span style="line-height: 1.5;">Introduced a half-day two-class comparison, feeling or directly on the demo to a little faster. Below I use the Open Sub-thread and open asynchronous two ways to achieve the download, while simple analysis of the two methods of the CPU execution sequence.</span></p></p><p><p><span style="line-height: 1.5;">1. Open child thread in current activity to perform the download</span></p></p><p><p><span style="line-height: 1.5;">(1) Create a download sub-thread:</span></p></p><pre><span style="color: #008080;"><span style="color: #008080;">1</span></span> <span style="color: #008000;"><span style="color: #008000;">/**</span></span><span style="color: #008080;"><span style="color: #008080;">2</span></span> <span style="color: #008000;"><span style="color: #008000;">* Download Thread</span></span><span style="color: #008080;"><span style="color: #008080;">3</span></span> <span style="color: #008000;"><span style="color: #008000;">*/</span></span><span style="color: #008080;"><span style="color: #008080;">4</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">Private</span></span>Thread MyThread =<span style="color: #0000ff;"><span style="color: #0000ff;">New</span></span>Thread (<span style="color: #0000ff;"><span style="color: #0000ff;">New</span></span><span style="color: #000000;"><span style="color: #000000;">Runnable () {</span></span><span style="color: #008080;"><span style="color: #008080;">5</span></span> <span style="color: #000000;"><span style="color: #000000;">@Override</span></span><span style="color: #008080;"><span style="color: #008080;">6</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;"></span> public</span> <span style="color: #0000ff;"><span style="color: #0000ff;">void</span></span><span style="color: #000000;"><span style="color: #000000;">Run () {</span></span><span style="color: #008080;"><span style="color: #008080;">7</span></span>Object Data=<span style="color: #000000;"><span style="color: #000000;">Download (PATH);</span></span><span style="color: #008080;"><span style="color: #008080;">8</span></span>Message msg=<span style="color: #000000;"><span style="color: #000000;">Message.obtain ();</span></span><span style="color: #008080;"><span style="color: #008080;">9</span></span>Msg.what=101<span style="color: #000000;"><span style="color: #000000;">;</span></span><span style="color: #008080;"><span style="color: #008080;">Ten</span></span>msg.obj=<span style="color: #000000;"><span style="color: #000000;">data;</span></span><span style="color: #008080;"><span style="color: #008080;"></span> one</span> <span style="color: #000000;"><span style="color: #000000;">handler.sendmessage (msg);</span></span><span style="color: #008080;"><span style="color: #008080;"></span> a</span> <span style="color: #000000;"><span style="color: #000000;"> }</span></span><span style="color: #008080;"><span style="color: #008080;"></span> -</span>});</pre><p><p>(2) perform the post-download tasks in Handler:</p></p><pre><span style="color: #008080;"><span style="color: #008080;">1</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">Private</span></span>Handler handler=<span style="color: #0000ff;"><span style="color: #0000ff;">New</span></span>Handler (<span style="color: #0000ff;"><span style="color: #0000ff;">New</span></span><span style="color: #000000;"><span style="color: #000000;">handler.callback () {</span></span><span style="color: #008080;"><span style="color: #008080;">2</span></span> <span style="color: #000000;"><span style="color: #000000;">@Override</span></span><span style="color: #008080;"><span style="color: #008080;">3</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;"></span> public</span> <span style="color: #0000ff;"><span style="color: #0000ff;">Boolean</span></span><span style="color: #000000;"><span style="color: #000000;">handlemessage (Message Msg) {</span></span><span style="color: #008080;"><span style="color: #008080;">4</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">if</span></span>(msg.what==101<span style="color: #000000;"><span style="color: #000000;">){</span></span><span style="color: #008080;"><span style="color: #008080;">5</span></span>Data=<span style="color: #000000;"><span style="color: #000000;">msg.obj;</span></span><span style="color: #008080;"><span style="color: #008080;">6</span></span> <span style="color: #008000;"><span style="color: #008000;">//</span></span><span style="color: #008000;">the <span style="color: #008000;">following actions are performed on data</span></span><span style="color: #008080;"><span style="color: #008080;">7</span></span> <span style="color: #000000;"><span style="color: #000000;"> }</span></span><span style="color: #008080;"><span style="color: #008080;">8</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">return</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">false</span></span><span style="color: #000000;"><span style="color: #000000;">;</span></span><span style="color: #008080;"><span style="color: #008080;">9</span></span> <span style="color: #000000;"><span style="color: #000000;"> }</span></span><span style="color: #008080;"><span style="color: #008080;">Ten</span></span>});</pre><p><p>(3) Open the current download thread where it needs to be downloaded:</p></p><p><p><span class="cnblogs_code"> <span style="color: #008080;">1</span> mythread.start ();</span></p></p><p><p>It's easy to download network requests with just three steps above, does it look simple? So the problem is that the download task is performed in the Mythread sub-thread, and if the download task is still in progress, the user performs a page jump, that is, the UI thread that the current activity is in is destroyed, but the mythread sub-thread is not destroyed. Then when mythread executes the download task download (), He then calls handler to send the message to perform the data operation, and the handler that performs the data operation is defined in the current Activity. With the destruction of the current activity, the current handler also with the destruction, so that in Mythread can not invoke the execution of data handler, then he will certainly report nullpointexception it. therefore, It is not safe to use child threads for download tasks.</p></p><p><p>2. Use asynchronous task Asynctask to perform download tasks</p></p><p><p>So in Android you can use native asynctask for time-consuming operations like downloading network requests, by creating a download task that inherits the Asynctask abstract class, overriding Doinbackground () in that class, This method is executed in the Sub-thread to be downloaded, point open asynctask source code, we can see in Doinbackground () This method has a comment @workthread, can think of this method is executed in the worker thread, So is there a way to execute it in the main thread? There are, of course, a few ways in which there are no statements in the body of their methods that can be overridden by subclasses, constructed by execute (), onpreexecute (), oncancelled () And so on are all executed in the Mainthread.</p></p><p><p>Then there may be a classmate to ask questions, so still in the Sub-thread to perform the task to download, do we say that the above-mentioned critical event, sub-thread download After the end of the null pointer is not the exception?</p></p><p><p>of course, You can certainly say that the use of asynctask will never happen to the above-mentioned bug, why? We went on to Analyze.</p></p><p><p>In addition to the Doinbackground () of the currently executing download in the worker thread, there is only publishprogress (), and Doinbackground () is an abstract method, so you want to know what kind of doorway the worker thread has, Can only find clues from publicprogress (). We know that this method is used when publishing progress, the following is the source code of this method,</p></p><pre><pre> <span style="color: #008080;">1 </span> <span style="color: #000000;"> @WorkerThread </span> <span style="color : #008080; ">2 </span> <span style="color: #0000ff;">protected </span> <span style="color: #0000ff;">final </span> <span style=" Color: #0000ff; ">void </span> <span style="color: #000000;" "> publishprogress (Progress ... values) {</span> <span style="color: #008080;">3 </span> <span style="color: #0000ff; >if </span> (!<span style=" color: #000000; "> iscancelled ()) {</span> <span style="color: #008080;">4 </span> <span style="color: #000000;"> gethandler (). Obtai Nmessage (message_post_progress, </span> <span style="color: #008080;">5 </span> <span style="color: #0000 ff; ">new </span> asynctaskresult<progress> (<span style="color: #0000ff;">this </span> <span style="color: #000000;" , "values"). sendtotarget (); < span> <span style="color: #008080;">6 </span> <span style="color: #000000;" } < span> <span style="color: #008080;">7 <!-- span-->} </span></span></span></pre></pre><p><p>It is obvious that this gethandler () is the handler object in the current Asynctask class, which means that the progress posted in the worker thread will send the information to the handler of the current asynctask, so we don't care how the work thread is going to publish it. , just take a look at how the received information is handled in the current Asynctask.</p></p><pre><span style="color: #008080;"><span style="color: #008080;">1</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">Private</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">Static</span></span><span style="color: #000000;"><span style="color: #000000;">Handler gethandler () {</span></span><span style="color: #008080;"><span style="color: #008080;">2</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">synchronized</span></span>(asynctask.<span style="color: #0000ff;"><span style="color: #0000ff;">class</span></span><span style="color: #000000;"><span style="color: #000000;">) {</span></span><span style="color: #008080;"><span style="color: #008080;">3</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">if</span></span>(shandler = =<span style="color: #0000ff;"><span style="color: #0000ff;">NULL</span></span><span style="color: #000000;"><span style="color: #000000;">) {</span></span><span style="color: #008080;"><span style="color: #008080;">4</span></span>Shandler =<span style="color: #0000ff;"><span style="color: #0000ff;">New</span></span><span style="color: #000000;"><span style="color: #000000;">Internalhandler ();</span></span><span style="color: #008080;"><span style="color: #008080;">5</span></span> <span style="color: #000000;"><span style="color: #000000;"> }</span></span><span style="color: #008080;"><span style="color: #008080;">6</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">return</span></span><span style="color: #000000;"><span style="color: #000000;">shandler;</span></span><span style="color: #008080;"><span style="color: #008080;">7</span></span> <span style="color: #000000;"><span style="color: #000000;"> }</span></span><span style="color: #008080;"><span style="color: #008080;">8</span></span>}</pre><p><p>This method is obviously in the shandler is not empty when the return of a Internalhandler object, the whole process is to Asynctask lock, and here is the key to lock, after all, to ensure the security of sending messages, After acquiring a internalhandler object, the entire asynctask is in locking State. Then we'll go and see what this internalhandler is for.</p></p><p><p>First we can be sure that this is a subclass of the inherited handler class, and only executes the following lines in his Handlermessage (), where the root of our problem should be found.</p></p><pre><span style="color: #008080;"><span style="color: #008080;">1</span></span>asynctaskresult<?> result = (asynctaskresult<?><span style="color: #000000;"><span style="color: #000000;">) msg.obj;</span></span><span style="color: #008080;"><span style="color: #008080;">2</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;">Switch</span></span><span style="color: #000000;"><span style="color: #000000;">(msg.what) {</span></span><span style="color: #008080;"><span style="color: #008080;">3</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;"></span> case</span><span style="color: #000000;"><span style="color: #000000;">message_post_result:</span></span><span style="color: #008080;"><span style="color: #008080;">4</span></span> <span style="color: #008000;"><span style="color: #008000;">//</span></span><span style="color: #008000;"><span style="color: #008000;">there</span> is only one result</span><span style="color: #008080;"><span style="color: #008080;">5</span></span>Result.mTask.finish (result.mdata[0<span style="color: #000000;"><span style="color: #000000;">]);</span></span><span style="color: #008080;"><span style="color: #008080;">6</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;"></span> break</span><span style="color: #000000;"><span style="color: #000000;">;</span></span><span style="color: #008080;"><span style="color: #008080;">7</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;"></span> case</span><span style="color: #000000;"><span style="color: #000000;">message_post_progress:</span></span><span style="color: #008080;"><span style="color: #008080;">8</span></span> <span style="color: #000000;"><span style="color: #000000;">result.mTask.onProgressUpdate (result.mdata);</span></span><span style="color: #008080;"><span style="color: #008080;">9</span></span> <span style="color: #0000ff;"><span style="color: #0000ff;"></span> break</span><span style="color: #000000;"><span style="color: #000000;">;</span></span><span style="color: #008080;"><span style="color: #008080;">Ten</span></span>}</pre><p><p>Found here the type of information sent to judge, there are only two types, the second message_post_progress, is not just the method of publishing progress Publicprogress () The type of information sent Inside. So the first kind of message_post_result, it's not hard to think, this is the type of information sent after executing doinbackground () in the worker thread, and there is already a comment stating that "there is the only one RESULT", " There is only one result ", after we get this message that our download task is done, we call the following method, but we don't have to look down again, because this method of execution is the current Asynctask's own finish (). This is exactly what it means to execute finish () in the main thread after the normal execution of the worker Thread's Doinbackground (), so our thinking is straightened Out.</p></p><p><p>well, Perhaps after reading the above code add my analysis, Some students feel more is foggy, it seems that there is no explanation of the middle jump problem ah. Then you have to think about it, before directly open the Sub-thread after the download of the root cause of a null pointer exception is where? is the null pointer exception that is generated when the handler object in the main thread cannot be used in the child THREADS. So how does our asynchronous task Asynctask solve the handler of sending the message?</p></p><p><p>When using handler to send information, the system calls GetHandler (), obtains a internalhandler object, if it was not previously created, if there is before, and because the entire process of the current asynchronous task Asynctask is locking state, So other threads cannot be used, and the same main thread that uses Asynctask cannot be destroyed at Will. In this way, the resulting handler will be returned using the sending message, and the null pointer can be crossed SMOOTHLY.</p></p><p><p><span style="line-height: 1.5;">Iii. Summary</span></p></p><p><p>So explain, believe that still in the mind of the students should understand a little, I would like to make a brief summary below.</p></p><p><p>Asynctask is an asynchronous task that performs time-consuming operations in addition to the task of updating the UI Interface. Updates to the UI interface are performed in the main thread, which is the UI thread, and in this asynchronous task, a worker thread is opened to perform time-consuming operations. The execution order of this worker thread and the UI thread is not synchronized, meaning that OnPostExecute () in the UI thread is not invoked to perform subsequent UI operations until the download in the worker thread has been performed, thus implementing an asynchronous Download. If the UI thread destroys and then sends the END-OF-DOWNLOAD information to the worker thread, it is bound to asynctask as the worker is reused, so he will destroy it as the current asynctask is destroyed, and will not perform subsequent download operations, and will naturally not perform the message to send the download end.</p></p><p><p>While simply opening a child thread to perform the download, the child thread and the UI thread simply maintain a simple synchronization relationship, so it is not safe to simply perform a download-time-consuming operation on a child thread. It turns out that although multithreading in Java is a good mechanism, you should pay attention to its side effects when you use it, and learn to use the classes and methods that have been encapsulated.</p></p><p><p> The difference between using thread threads in Android and Asynctask asynchronous tasks </p> </p></span>
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.