1. One problem
There is such a problem that deserves our consideration. If we write some functions similar to the download function that is time-consuming and does not necessarily have results) in the Activity (main thread), it will cause Activity blocking, no response for a long time until the page is suspended (if the page is not completed in five seconds, an error message "force close" will be received from the Android system "). Therefore, we need to put these time-consuming operations in separate child threads. This is the mission of Handler. Handler provides the asynchronous processing function. Sending and receiving are not the same (the main thread of the Activity and threads in the thread queue are different threads, which are executed in parallel without affecting each other ).
Ii. Handler Introduction
Handler is a thread communication tool in the Android operating system. It mainly plays two roles: (1) arranging a message or Runnable to execute somewhere in a main thread (2) schedule an action to be executed in another thread. Each Handler object maintains two queues (FIFO), message queue, and Runnable queue, which are provided by the Android operating system. Handler can use these two queues to separate:
Handler can be used in three steps: 1. Create a Handler object. 2. Create Runnable and message. 3. Call the post and sendMessage methods to add Runnable and message to the queue.
3. Runnable queue
1. threads in java
In java, there are two ways to create a Thread: Inherit the Thread class and implement the Runnable interface. The most important thing is to re-write the run method to implement the thread function. When the time slice of the thread arrives, the run () function is executed and the execution is complete, and the process enters the dead state.
Example of creating a thread:
- Runnable r=new Runnable(){
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- System.out.println("thread");
- handler.postDelayed(thread, 3000);
- }
- };
2. About Runnable queue
(1) Principle
Android thread asynchronous processing mechanism: the Handler object maintains a thread queue. When a new Runnable is sent to post (), it is placed at the end of the queue. When Runnable is processed, extract Runnable from the team header for execution. When a Runnable is sent to the queue, it returns immediately, regardless of whether the Runnable is executed or whether the execution is successful. The specific execution is performed by the system after the Runnable is queued. This is like an example of a post office. The sender writes the mail and puts it in the mail box to go home. He does not know when the mail is delivered by the post office, when it is sent, and how the recipient reads the mail. In this way, Android asynchronous processing is implemented.
(2) specific operations
Add thread to queue:
Handler. post (Runnable); add Runnable directly to the queue
Handler. postDelayed (Runnable, long) after a certain delay, add Runnable to the queue
Handler. postAtTime (Runnable, long) regularly adds Runnable to the queue
Termination thread:
Handler. removeCallbacks (thread); extract Runnable from Runnable queue
4. Message Queue
1. Message object
(1) Message object
The Message object carries data. Generally, it uses arg1 and arg2 to transmit messages. Of course, it can also have the obj parameter and can carryBundleData. It features a low consumption of system performance.
Initialization: Message msg = handler. obtainMessage ();
(2) Bundle object
Bundle is a class provided by Android. It can be considered as a special Map, that is, a key-Value Pair package. In particular, keys and values must be the basic data type or the key value of the basic data type array Map must be an object). In particular, keys must be of the String type. Use Message to carry Bundle data:
Put: msg. setData (Bundle bundle );
Retrieve: msg. getData ();
2. About message queues
(1) Principle
Android message asynchronous processing mechanism: the Handler object maintains a message queue. When a new message is sent to sendMessage (), it is placed at the end of the queue and then queued to process the message, handleMessage () is processed by the Handler object of the main thread ()). The entire process is asynchronous, which is the same as the Runnable queue.
(2) specific operations:
Add Runnable: handler. sendMessage (Message) to the queue );
Send the message to message queue msg. sendToTarget ();
After a delay of some time, send the Message to the Message Queue handler. sendMessageDelayed (Message, long );
Regularly send messages to the Message Queue handler. sendMessageAtTime (Message, long)
Message Processing:
The handleMessage (Message msg) method of Handler needs to be rewritten using the anonymous internal class when the new Handler object is used, as follows:
- Handler handler=new Handler(){
-
- @Override
- public void handleMessage(Message msg) {
- // TODO Auto-generated method stub
- 。。。。。。
-
- 。。。。。。
- }
- };
5. Two Functions of Handler
1. Schedule a message or Runnable to be executed somewhere in a main thread
Sample Code:
- public class HandlerTestActivity extends Activity {
- private Button start;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.handlertest);
- start=(Button) findViewById(R.id.start);
- start.setOnClickListener(new startListener());
-
- System.out.println("Activity Thread:"+Thread.currentThread().getId());
- }
- Handler handler=new Handler();
- Runnable thread=new Runnable(){
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- System.out.println("HandlerThread:"+Thread.currentThread().getId());
-
- }
- };
- class startListener implements OnClickListener{
-
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- handler.post(thread);
- }
- }
-
- }
In this small program, first start the program and enter onCreate), print the ID of the current thread (the main thread), and then click start to add the thread to the thread queue column, the thread is used to print the ID of the current thread. In this program, we can see that through Handler we can arrange Runnable to execute somewhere in a main thread, that is, role (1 ).
But there is a small trap. Have you found it? This program seems to have implemented the asynchronous mechanism of Handler, and handler. post (thread) seems to have implemented the role of a new startup thread. However, through execution, we find that the IDs of the two threads are the same! That is to say, in fact, the thread is still the original main thread. It can be seen that the handler. post () method does not actually create a new thread, but is only executed on the original thread. We have not implemented the asynchronous mechanism.
2. Schedule an action to be executed in another thread.
(1) java standard thread Creation Method
Step 1:
- Runnable r=new Runnable(){
-
- @Override
- public void run() {
- // TODO Auto-generated method stub
- System.out.println("thread");
- handler.postDelayed(thread, 3000);
- }
- };
Step 2:
- Thread t=new Thread (r);
Step 3:
- t.start();
If you change the handler. post (thread); statement in the preceding example program to the preceding format, we can see that the two IDs are different and the new thread starts!
(2) about Logoff
The logoff class is used to enable a message loop for a thread to read messages from the Message Queue cyclically. Therefore, logoff is actually the encapsulation of Message Queue + message loop. Each thread can correspond to only one logoff. Except for the main thread, the Android thread does not enable logoff by default.
Through Handler interaction with logoff, Handler can be seen as a logoff interface, used to send messages to a specified logoff and define the processing method. By default, Handler is bound to the Logoff of the thread where it is located, that is:
Handler handler = new Handler (); equivalent to Handler handler = new Handler (lofter. mylofter ());
Logoff has two main methods:
Lorule. prepare (); Enable lorule
Logoff. loop (); enables logoff to start working, fetch messages from the message queue, and process messages.
Note: Write it in logoff. the code after loop () will not be executed. This function should be a loop. When mHandler is called. getLooper (). after quit (), the loop will be aborted, and the subsequent code can be run.
(3) Implementation of Handler asynchronous mechanism
Handler uses HandlerThread to make the sub-thread and the main thread belong to different threads. In fact, HandlerThread is a special thread, which encapsulates logoff,
Sample Code:
- // Create a HandlerThread object named handler_hread
- HandlerThread handlerThread = new HandlerThread ("handler_hread ");
-
- // Enable handlerThread. You must call the start method before using handlerThread. getLooper (); otherwise, the result is empty.
- HandlerThread. start ();
-
- // Bind the handler to The logoff of the handlerThread, that is, the handler is running in the handlerThread.
- MyHandler handler = new myHandler (handlerThread. getLooper ());
-
- Class myHandler extends Handler {
- Public myHandler (){}
- Public myHandler (low.logoff ){
- Super (logoff );
- }
- @ Override
- Public void handleMessage (Message msg ){
- // TODO Auto-generated method stub
- System. out. println ("Activity Thread:" + Thread. currentThread (). getId ());
- }
- }
In this way, the asynchronous Processing Mechanism of handler is implemented. by calling the handler. post () method, we can know that the subthread and the main thread belong to different threads by printing the thread ID.