I will talk about Handler this time. Why does Handler feature? First, the previous basic controls are basically called and processed in the onCreate (Bundle savedInstanceState) method of the Activity. However, in some cases, for example, if you want to download software from the network and wait for a long response time, if the software is also stored in the Activity method, When you execute this method, the whole Activity is inmovable, and users can only wait. This user experience is very poor. The best result of this processing method is that after waiting for a while, the expected result is obtained. The bad situation is that after waiting for N for a long time, there is no result, and some may even cause the Activity to report an error. To avoid these situations, the Handler feature is introduced, it is like a thread queue, and it is also an asynchronous message processing.
First, let's take a look at an example to understand Handler.
In the layout file, there are two buttons: start and stop, respectively, which control the start and stop of the thread respectively.
<Button
Android: id = "@ + id/start"
Android: layout_height = "wrap_content"
Android: layout_width = "fill_parent"
Android: text = "@ string/start"
/>
<Button
Android: id = "@ + id/stop"
Android: layout_height = "wrap_content"
Android: layout_width = "fill_parent"
Android: text = "@ string/stop"
/>
The code in the Activity is as follows:
Import android. app. Activity;
Import android. OS. Bundle;
Import android. OS. Handler;
Import android. view. View;
Import android. view. View. OnClickListener;
Import android. widget. Button;
Public class HandlerDemo1Activity extends Activity {
Button startButton = null;
Button endButton = null;
Handler handler = new Handler ();
/** Called when the activity is first created .*/
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
StartButton = (Button) findViewById (R. id. start );
StartButton. setOnClickListener (new StartListener ());
EndButton = (Button) findViewById (R. id. end );
EndButton. setOnClickListener (new EndListener ());
}
Class StartListener implements OnClickListener {
@ Override
Public void onClick (View arg0 ){
// TODO Auto-generated method stub
Handler. post (HandlerThread );
}
}
Class EndListener implements OnClickListener {
@ Override
Public void onClick (View arg0 ){
// TODO Auto-generated method stub
Handler. removeCallbacks (HandlerThread );
}
}
Runnable HandlerThread = new Runnable (){
@ Override
Public void run (){
// TODO Auto-generated method stub
System. out. println ("HandlerThread is Running ......");
Handler. postDelayed (HandlerThread, 3000 );
}
};
}
We can see that the two buttons in the Activity are respectively bound to the event listener, an instance of Handler is created, and an anonymous internal class is created, which is a thread HandlerThread that implements the Runnable interface.
When the start button is pressed, handler is executed. post (HandlerThread); As mentioned before, Handler uses a thread queue. This Code adds the HandlerThread to the thread queue of handler, because the HandlerThread added is the first thread, it will immediately execute its run () method. In the run () method, handler. postDelayed (HandlerThread, 3000); again put HandlerThread into the thread queue of handler. A latency of MS is set here. In this way, the entire program will continue to run and print "HandlerThread is Running ......" in LogCat every Ms ......".
However, it is worth noting that we should not consider handler's appearance to separate the thread where these print operations are located from the main thread. Otherwise, no two threads are running, the printed content is also run by the main thread. We can make an experiment to pass the name of the current Thread through the Thread after the onCreate function and where the print statement is located. currentThread. when getName () is printed, it can be seen that all of them are the same and all are the main ones, which means that all of them are run by the main thread. We know that the start () method is required to start a thread. In this program, the start () method is called directly instead of the HandlerThread. So it's not surprising that the main thread is running.
From the above example, if Handler is used in this way, it is not what we want, because it does not implement Asynchronization or runs in a main thread.
Therefore, Handler must be used in another way.
To Implement Asynchronous multithreading of Handler, you need to understand the other two classes, one is the Message class and the other is the logoff class.
Each Handler object has a Message queue, which is the stored Message object. You can use obtainMessage () to obtain the Message object. At the same time, the Message Object is used for transmission and use. It can transmit two integers and one Object. Try to use the arg1 and arg2 Integers of the Message to transmit parameters, in this way, the system consumes the least (API said). If the transmitted data volume is large, you can use the setData (Bundle a) method. The Bundle object can be roughly considered as a Map object, however, its keys are all strings, while values are limited types. You can view them in the API.
The logoff class can obtain messages cyclically from the message queue. We can use logoff in a thread so that the thread can obtain messages cyclically in the message queue, the message queue is empty. However, we generally do not directly create and use logoff. In the HandlerThread class provided by Android, we implement the logoff function. Therefore, we only need to use the HandlerThread class, we use the HandlerThread object to call getLooper () to obtain the Looper object of the thread.
Let's take a look at the example below
Import android. app. Activity;
Import android. OS. Bundle;
Import android. OS. Handler;
Import android. OS. HandlerThread;
Import android. OS. logoff;
Import android. OS. Message;
Public class HandlerDemo2Activity extends Activity {
/** Called when the activity is first created .*/
@ Override
Public void onCreate (Bundle savedInstanceState ){
Super. onCreate (savedInstanceState );
SetContentView (R. layout. main );
System. out. println ("Activity ---->" + Thread. currentThread (). getName ());
HandlerThread handlerThread = new HandlerThread ("HandlerThread"); // create a HandlerThread object, which is a thread
HandlerThread. start (); // start the thread
MyHandler myHandler = new MyHandler (handlerThread. getLooper (); // create a MyHandler object, which inherits Handler. From the MyHandler class below, we can see that the Handler (Looper loler) of the Handler parent class is called) and the logoff object passed in here is obtained from HandlerThread.
Message msg = myHandler. obtainMessage (); // get the Message object
Msg. sendToTarget (); // send the received message object to the Handler that generates the message, that is, myHandler. When myHandler receives the message, it calls its handleMessage method to process the message.
}
Class MyHandler extends Handler {
Public MyHandler () {// Constructor
// TODO Auto-generated constructor stub
}
Public MyHandler (low.logoff) {// Constructor
Super (logoff); // implements the constructor of the parent class.
}
@ Override
Public void handleMessage (Message msg) {// This method is automatically called when the Handler receives the Message object to process the Message object.
// TODO Auto-generated method stub
System. out. println ("Handler ---->" + Thread. currentThread (). getName ());
}
}
}
The execution result of the above Code in System. out in LogCat is:
Acitivity ----> main
Handler ----> HandlerThread
This shows that Handler, combined with logoff and Message, can be used to achieve separation from the main thread, thus implementing multithreading and asynchronous processing.
The above is just a personal talk about Handler. the attachment is the code of two examples for your reference only.
This article is from the "Temple of war" blog