Android Hnadler, Message, Looper

The definition of Handler:

      Mainly accept thread to send data, and use this data to update the UI with the main thread.

Why use Handler?

      Many of our mobile phone function or operation is not on the Activity, such as downloading files, handling large amounts of data, complex operation, fault. If placed in the Activity (which is the main thread) words, there will be long time no response, even like the ANR error occurred (i.e. 5 seconds no response), it will cause a poor user experience, so it shows the necessity of Handler. If we get those time-consuming operation in another thread operations, so that you can and the main thread (UI) thread synchronization operation, does not appear to wait for a long time or no response operation, the user experience is improved greatly. One of the things Handler is to realize the above functions.


[A]

We first use a simple example to demonstrate the basic use of Handler:

1, First create a Handler object, you can directly use the Handler parameterless constructor to create an Handler object,

2, In the listener, call the post method of Handler, will be the implementation of the thread object is added to the thread queue. This will put the thread object is added to the handler

3, The operation to be performed on the run method the thread object, usually a Runnable object, the run method which can copy.


Running effect diagram:

We then click the starthandler button, the output frame will be output once every three seconds after start, until we hit the endhandler button, the output frame information would not be output.

The main code:

 1 public class MainActivity extends Activity {
 2     
 3     private Button mStartButton,mEndButton;
 4     @Override
 5     public void onCreate(Bundle savedInstanceState) {
 6         super.onCreate(savedInstanceState);
 7         setContentView(R.layout.activity_main);
 8         mStartButton = (Button)findViewById(R.id.start);
 9         mEndButton = (Button)findViewById(R.id.end);
10         
11         mStartButton.setOnClickListener(new StartButtonListener());
12         mEndButton.setOnClickListener(new EndButtonListener());
13     }
14     
15     private class StartButtonListener implements OnClickListener{
16         @Override
17         public void onClick(View v) {
18             //Immediately the thread object is added to the handler message queue to queue, a FIFO data structure, then the thread object is removed from the message queue will execute run () method. 
19             handler.post(runnable);
20         }
21     }
22     private class EndButtonListener implements OnClickListener{
23         @Override
24         public void onClick(View v) {
25             /*The thread object runnable from the handler message queue remove., 
26             Not the message queue will have this thread object runnable, also won't execute run () method.*/
27             handler.removeCallbacks(runnable);
28         }
29     }
30     //Create a handler object, each handler has an associated message queue
31     Handler handler = new Handler();
32     //The operation to be performed on the thread object (run) method
33     Runnable runnable = new Runnable() {
34         @Override
35         public void run() {
36             System.out.println("start");
37             //Delay of 3000 milliseconds to thread object is added to the message queue to, every 3000 milliseconds added time, cycle
38             handler.postDelayed(runnable, 3000);
39         }
40     };
41 }

[Two]

Under the realization of a ProgressBar automatic update using the Handler:

Running effect diagram:

When we click on the starthandler button, ProgressBar will update, add the same units per second.

1, First create a Handler object, Handler class inheritance, overriding the handleMessage method to create a Handler object.
2, In the listener, call the post method of Handler, will be the implementation of the thread object is added to the thread queue. This will add the thread object to a handler object in the queue of threads.
3, The operation to be performed on the run method the thread object, usually a Runnable object, the run method which can copy.
Handler contains two queues, one of which is the thread queue, another is the message queue. Use the post method will thread object on the handler thread in the queue, use sendMessage (Message message) the message in the message queue.
If you want this process has been implemented, can be in inside the run method executes the postDelayed or post method, and then add the thread object to message queue, repeat. Want to stop the execution of threads, Handler object called removeCallbacks (Runnable R) method from the thread queue thread object, the thread execution stops.

Handler provides an asynchronous message handling mechanism for Android, When sending a message to the messages in the queue (sendMessage) immediately after the return, And read the message queue will be blocked, Which reads the message from the message queue will perform in Handler public void handleMessage (Message MSG) method, So you should use an anonymous inner class to override this method to create Handler, In this method write read the news after the operation, the use of Handler (obtainMessage) to obtain the message object.

The main code:

 1 public class MainActivity extends Activity {
 2 
 3     private Button mStartButton = null;
 4     private ProgressBar mProgressBar = null;
 5     private int i=0;
 6     @Override
 7     public void onCreate(Bundle savedInstanceState) {
 8         super.onCreate(savedInstanceState);
 9         setContentView(R.layout.activity_main);
10         
11         mStartButton = (Button)findViewById(R.id.start);
12         mProgressBar = (ProgressBar)findViewById(R.id.progressBar);
13         
14         mStartButton.setOnClickListener(new StartListener());
15     }
16     public class StartListener implements OnClickListener{
17         @Override
18         public void onClick(View arg0) {
19             handler.post(runnable);
20         }
21     }
22     Handler handler = new Handler(){
23         @Override
24         public void handleMessage(Message msg) {
25             super.handleMessage(msg);
26             mProgressBar.setProgress(msg.arg1);
27             handler.post(runnable);
28             if(msg.arg1==100){
29                 handler.removeCallbacks(runnable);
30                 mProgressBar.setProgress(0);
31                 handler.post(runnable);
32                 i=0;
33             }
34         }
35     };
36     Runnable runnable = new Runnable() {
37         @Override
38         public void run() {
39             i = i+10;
40             Message message = handler.obtainMessage();
41             //The message object is the value of the parameter is set to I
42             message.arg1 = i;
43             try {
44                 Thread.sleep(1000);
45             } catch (InterruptedException e) {
46                 // TODO Auto-generated catch block
47                 e.printStackTrace();
48             }
49             if(i==100){
50                 handler.removeCallbacks(runnable);
51                 mProgressBar.setProgress(0);
52             }
53             handler.sendMessage(message);
54         }
55     };
56 }

[Three]

The relationship between Handler and thread:
The post method using the Handler Runnable object in a Handler thread in the queue, the Runnable implementation is not open alone thread execution, but still in the current Activity thread, Handler just call the run method of the Runnable object.

We use an example to prove it, we print with the thread ID that they are actually in the same thread running.

Running effect diagram:

If the code we use:

//Thread thread = new Thread(runnable);
//thread.start();

This way start a thread if thread ID and name will be different, running effect diagram as follows:

The main code as follows:

 1 public class MainActivity extends Activity {
 2     Handler handler = new Handler();
 3     @Override
 4     public void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         //handler.post(runnable);
 7         
 8         setContentView(R.layout.activity_main);
 9         Thread thread = new Thread(runnable);
10         thread.start();
11         System.out.println("ID============:"+Thread.currentThread().getId());
12         System.out.println("NAME:"+Thread.currentThread().getName());
13     }
14     Runnable runnable = new Runnable() {
15         @Override
16         public void run() {
17             System.out.println("RUNABLEID:::::::::::"+Thread.currentThread().getId());
18             System.out.println("RUNABLENAME:"+Thread.currentThread().getName());
19             try {
20                 Thread.sleep(10000);
21             } catch (InterruptedException e) {
22                 // TODO Auto-generated catch block
23                 e.printStackTrace();
24             }
25         }
26     };
27 }

[Four]

We transfer data through message, and finally in the handleMessage () to print out our data transfer method.

What is Bundle:
Bundle is a special map, it is the transmission of information tools, key only it is of type string, and the value is the basic data of common types.
How to make Handler Runnable to open a new thread:
1, First create a HandlerThread object, implements the use of Looper to process the message queue functions, this class by the Android application framework
  HandlerThread handlerThread = new HandlerThread("handler_thread");
2, In the use of HandlerThread getLooper () method, you must call the start(); handlerThread.start();
3, Get the Looper object in the HandlerThread object. The successor to the 4, to create a custom Handler class, which implements a method to construct the parameters for the Looper object, method call the superclass constructor.
5, Create a custom obtained using third step Looper object Handler subclass object, then the message (Message) sent to the Handler message queue, Handler carbon handleMessage () will be executed to handle in the message queue.

The message, the Message object, you can pass on some information, you can use the arg1.arg2, Object transfer some plastic or object, you can also use the Message object's setData (Bundle bundle) is the Bundle object passed to the newly created thread, thread in the implementation of handleMessage (Message MSG) can make use of getData from message (extracted) a Bundle object for processing.

The implementation effect chart:

The main code:

 1 public class MainActivity extends Activity {
 2 
 3     @Override
 4     public void onCreate(Bundle savedInstanceState) {
 5         super.onCreate(savedInstanceState);
 6         setContentView(R.layout.activity_main);
 7         System.out.println("Activity------------->"+ Thread.currentThread().getId());
 8         
 9         HandlerThread handlerThread = new HandlerThread("handlerThread");
10         //In the use of handlerThread (getLopper) must first call the start method of the class (before) method, otherwise it will report a null pointer
11         handlerThread.start();
12         
13         MyHandler myHandler = new MyHandler(handlerThread.getLooper());
14         Message message = myHandler.obtainMessage();
15         //Send msg to the target object, the object is to generate the MSG object, handler object
16         Bundle bundle = new Bundle();
17         bundle.putInt("age", 23);
18         bundle.putString("name", "gaojicai");
19         message.setData(bundle);
20         
21         message.sendToTarget();
22     }
23     
24     public class MyHandler extends Handler{
25 
26         public MyHandler() {
27             super();
28         }
29         public MyHandler(Looper looper) {
30             super(looper);
31             
32         }
33 
34         @Override
35         public void handleMessage(Message msg) {
36             super.handleMessage(msg);
37             Bundle bundle = msg.getData();
38             int age = bundle.getInt("age");
39             String name = bundle.getString("name");
40             System.out.println("age---->"+age+",name------->"+name);
41             
42             System.out.println("Handler------------->"+ Thread.currentThread().getId());
43             System.out.println("handleMessage");
44         }
45     }
46 }


All project code download

Posted by Edgar at November 19, 2013 - 11:47 AM