There is an article about the Android thread is very good, you can refer to the following, which has a very good sentence, take it as the opening sentence:
When a program starts for the first time, Android initiates a corresponding main thread, which is primarily responsible for handling UI-related events, such as user keystroke events, User touch screen events, and screen drawing events, and distributing related events to the corresponding components for processing. So the main thread is often called the UI thread. The principle of a single-threaded model must be adhered to when developing Android apps: Android UI operations are not thread-safe and must be executed in the UI thread.
The first time I touch the Android threading background is this:
1: One HTTP interaction in demand
The steps are probably like this
1.1: Click the Submit button
1.2:http getting results synchronously
1.3: Writes the result to the TextView.
In this case, the execution will be error-able to initiate a synchronous HTTP network request on the UI thread. (Time consuming may cause anr,application not respond)
2:ok, since HTTP requests cannot be initiated on the UI thread, we will open a new child thread.
So the step becomes this:
1.1: Click the Submit button
1.2: Turn on a sub-thread
1.3:http getting results synchronously
1.4: Writes the result to the TextView.
One execution, BOOM, error, probably meaning that the sub-line thread can not directly manipulate UI elements, why? Please look at the sentence at the beginning of this article (thread safety).
3: OK, let's manipulate the UI elements through handler in a sub-thread.
Finally, the code passed by the test is probably like this
1.1: Click the Submit button
1.2: Turn on a sub-thread
1.3:http getting results synchronously
1.4: Pass the result as a message to handler
1.5: Write the results to TextView on the handler.
Tips: If you use the code inspect feature of Android Studio, you will find that it prompts you to do this, which may lead to memory leaks, why? Because handler holds a reference to the elements inside the UI, when the UI ends itself (handler is still waiting patiently for HTTP access results), it is found that an element is Hnadler held and cannot be recycled by GC, which can result in a memory leak. The workaround is simple, handler to static, eliminate the internal anonymous reference, and change the object's reference to weakreference<>. A detailed explanation of the reasons for the article, the specific code refer to the following, from our Address Book app
Static classImagedonehandlerextendsHandler {weakreference<ImageView>ImageView; WeakReference<Bitmap>bitmap; WeakReference<String>URL; Zimage.cachetype CacheType; Imagedonehandler (Looper Looper, ImageView _imageview, Bitmap _bitmap, String URL, zimage.cachetype cachetype) { Super(Looper); ImageView=NewWeakreference<>(_imageview); Bitmap=NewWeakreference<>(_BITMAP); This. url =NewWeakreference<>(URL); This. CacheType =CacheType; } @Override Public voidhandlemessage (Message msg) {if(Msg.what! =Msg_image_load_done)return; ImageView _imageview=Imageview.get (); Bitmap _bitmap=Bitmap.get (); String _url=Url.get (); if(_imageview = =NULL|| _bitmap = =NULL) return; if(_url.equals (_imageview.gettag (). toString ())) {_imageview.setimagebitmap (_BITMAP); if(CacheType = =ZImage.CacheType.DiskMemory) zimage.getinstance (). Puttomemorycache (_url, _bitmap); } } }
Write to now, I still do not understand, why handler inside can change UI inside of element?
This is the time to understand the four parts of the Android Asynchronous message processing (message, Handler, MessageQueue, and Looper).
I Caishuxueqian, so the following knowledge from the "first line of code" book excerpt fragments, very exciting, worth repeating reading, we take a deep breath, fasten the seat belt, began to ~
Let's start with an entire flow diagram of asynchronous message processing, which is more intuitive to follow (the first line of code)
1. Message
A message is an information that is passed between threads, which can carry a small amount of info inside a line
Exchange data between processes. In the previous section, we used the What field of the Message, in addition to making
Use the Arg1 and Arg2 fields to carry some integer data, using the Obj field to carry a single Object object.
2. Handler
Handler, as the name implies, is the meaning of the processor, which is primarily used to send and process messages. Send and Cancel
The Handler SendMessage () method is used, and the messages sent are processed in a series of
Will eventually be passed to Handler's Handlemessage () method.
3. MessageQueue
MessageQueue is the meaning of Message Queuing, which is primarily used to store all messages sent through Handler.
This part of the message will remain in the message queue and wait for it to be processed. There will only be one MessageQueue in each thread
Object.
4. Looper
Looper is the steward of MessageQueue in each thread, and after calling the Looper loop () method, it
into an infinite loop, and then whenever a message is found in the MessageQueue, it is taken
and passed to the Handler handlemessage () method. There will only be one Looper object in each thread.
After understanding the basic concepts of message, Handler, MessageQueue, and Looper, let's comb through the entire process of asynchronous message processing.
1: First you need to create a Handler object in the main thread and override the Handlemessage () method.
2: Then when UI action is required in a child thread, a message object is created and sent through Handler.
3: The message is then added to the MessageQueue queue for processing,
4: While Looper tries to remove the pending message from the MessageQueue, it is finally distributed back to the handler Handlemessage () method.
5: Since Handler is created in the main thread, the code in the Handlemessage () method will also run in the main thread, so we can do the UI operation safely here.
Asynctask Asynchronous Task Class
Fortunately, on most occasions, Android provides us with a asynctask asynchronous Task abstraction class that enables him to perform various time-consuming operations very conveniently without worrying about the UI thread being stuck, It also avoids the tedious writing of native asynchronous threads interacting with the UI thread.
When inheriting, we can specify three generic parameter types (all reference types Oh, value types are also changed to reference types, such as int->integer), respectively:
1: Parameter param, passed to sub-thread execution
2: Progress hint progress, if you need to update the asynchronous processing progress in real-time interface, you can use this parameter feedback
3: result, in the main thread, we get the result of the asynchronous execution.
Let's take an example.
/*** HTTP request user is present, enter HTTP URL address, return Boolean type exists*/ classQueryuserexisttaskextendsAsynctask<string,void,boolean> { /*** Before an asynchronous request is processed*/@Overrideprotected voidOnPreExecute () {Super. OnPreExecute (); } /*** Asynchronous processing, here also cannot interact UI elements Oh *@paramparams *@return */@OverrideprotectedBoolean doinbackground (String ... params) {return NULL; } /*** Asynchronous processing finished, cut back to the main thread, return processing results *@paramAboolean*/@Overrideprotected voidOnPostExecute (Boolean aboolean) {Super. OnPostExecute (Aboolean); } }
Invocation Example:
New Queryuserexisttask (). Execute ("Http://192.168.1.1/u/kimmy");
Summarize:
1: It is important to keep the main thread flowing, and the resource-intensive work is done as much as possible on the child threads.
2: In most cases, Asynctask is capable of asynchronous tasks.
3: When high-concurrency asynchronous tasks or asynchronous tasks need to be scheduled with each other, you need to write your own thread pool to handle
Android Threading Learning Experience