Android Handler and HandlerThread instances

Source: Internet
Author: User

Android Handler and HandlerThread instances

When an application is started, Android starts a main thread (that is, the UI thread) and the main thread distributes events for the UI controls in the management interface. For example, click a Button, android will distribute events to the Button to respond to your operations. If a time-consuming operation is required at this time. For example, when reading data online or reading a large local file, you cannot put these operations in the main thread. If you put them in the main thread, the interface may be suspended, if the task is not completed in five seconds, you will receive an error message "Force disable" from the Android system ". At this time, we need to put these time-consuming operations in a sub-thread. Because the sub-thread involves UI update, the main Android thread is thread insecure, that is, updating the UI can only be updated in the main thread. Operations in the Child thread are dangerous. At this time, Handler emerged to solve this complicated problem. Because Handler runs in the main thread (in the UI thread), it and the sub-thread can transmit data through the Message object, at this time, Handler undertakes to receive the Message object (containing data) transmitted by the subthread using the sendMessage () method, and puts the messages into the main thread queue, UI updates with the main thread.


Handler uses instance 1,

This example describes how to bind a Handler to the thread it creates. The function completed by this instance is: Click the start button, the program starts to start the thread, and the thread continues to start after 1 s delay after the completion of the program, the interface output UpdateThread is completed in the run function of each thread... text to stop running. When you click the "end" button, the thread stops. If you continue to click "start", the text is output again.


Source code:

Package com. example. handlertest; 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; import android. widget. textView; public class MainActivity extends Activity {private TextView text_view = null; private Button start = null; private Button end = null; // when using handler, you must first create a handler Handler handler = new Handler (); // you can use the runnable interface to process multiple threads using handler, the Runnable update_thread = new Runnable () {public void run () {// output "UpdateThread... "text, \ n is the automatic line feed text_view.append (" \ nUpdateThread... "); // after 1 s delay, add the thread to the thread queue handler. postDelayed (update_thread, 1000) ;};@ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); text_view = (TextView) findViewById (R. id. text_view); start = (Button) findViewById (R. id. start); start. setOnClickListener (new StartClickListener (); end = (Button) findViewById (R. id. end); end. setOnClickListener (new EndClickListener ();} private class StartClickListener implements OnClickListener {public void onClick (View v) {// TODO Auto-generated method stub // send the thread interface to handler in the thread queue immediately. post (update_thread) ;}} private class EndClickListener implements OnClickListener {public void onClick (View v) {// TODO Auto-generated method stub // remove handler from the thread queue. removeCallbacks (update_thread );}}}
Layout file:

<LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android" xmlns: tools = "http://schemas.android.com/tools" android: layout_width = "match_parent" android: layout_height = "match_parent" android: orientation = "vertical"> <TextView android: id = "@ + id/text_view" android: layout_width = "fill_parent" android: layout_height = "200dip" android: text = "@ string/hello_world" tools: context = ". mainActivity "/> <Button android: id =" @ + id/start "android: layout_width =" fill_parent "android: layout_height =" wrap_content "android: text = "start"/> <Button android: id = "@ + id/end" android: layout_width = "fill_parent" android: layout_height = "wrap_content" android: text = "end"/> </LinearLayout>


Handler uses instance 2,

This example is a little more complex than the previous example. In this example, the Handler message queue mechanism is used, that is, a thread in Handler sends messages to the Message Queue using the sendMessage method. The sent messages can of course be used to pass parameters. HandleMessage is used in Handler to process messages. The processing method is to obtain the message parameters in the message queue and use these parameters to complete other functions.
In this example, when the Start button is pressed, a thread is started and bound to Handler. The thread sends a message with parameters to the handler message queue, the other end of the Message Queue obtains the message and uses the parameter of the message to update the progress bar.


Source code:

Package com. example. handlertest; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. OS. message; import android. view. view; import android. view. view. onClickListener; import android. widget. button; import android. widget. progressBar; public class MainActivity extends Activity {private ProgressBar progress_bar = null; private Button start = null; @ Overridepublic void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); progress_bar = (ProgressBar) findViewById (R. id. progress_bar); start = (Button) findViewById (R. id. start); start. setOnClickListener (new StartOnClickListener ();} private class StartOnClickListener implements OnClickListener {public void onClick (View v) {// display the progress bar progress_bar.setVisibility (View. VISIBLE); // Add the thread to the thread queue of the handler. update_progress_bar.post (update_thread) ;}// create a handler and complete the internal message processing method Handler update_progress_bar = new Handler () {@ Overridepublic void handleMessage (Message msg) {// super. handleMessage (msg); // display progress bar progress_bar.setProgress (msg. arg1); // re-Add the process to the process queue update_progress_bar.post (update_thread) ;}; // without this semicolon, the Code Runnable update_thread = new Runnable () cannot be automatically added () {int I = 0; public void run () {// TODO Auto-generated method stubi + = 10; // first obtain a Message structure Message msg = update_progress_bar.obtainMessage (); // assign msg to the arg1 parameter of the message structure. arg1 = I; // The latency is 1 s. try + catch in java is used to troubleshoot try {Thread. sleep (1000);} catch (InterruptedException e) {// TODO: handle effectione. printStackTrace ();} // send the message to update_progress_bar.sendMessage (msg) in the message queue; if (I = 100) {// remove the thread from the thread queue update_progress_bar.removeCallbacks (update_thread );}}};}
Layout file:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical" >    <Button         android:id="@+id/start"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_alignParentBottom="true"        android:text="@string/start"        />    <ProgressBar         android:id="@+id/progress_bar"        android:layout_width="fill_parent"        android:layout_height="100dip"        android:layout_alignParentTop="true"        style="?android:attr/progressBarStyleHorizontal"        android:visibility="gone"        /></LinearLayout>
Handler instance 3,
The above two examples show that Handler uses the post method to start runnbale. In fact, the starting thread is the same as the main thread of the activity because it only runs the run method of the thread, instead of the start method. The purpose of instance 3 is to verify whether the post method of Handler is in the same thread.
The instance prints two pieces of information about the current thread in the onCreate function of the main activtiy, then creates a Handler and binds it to a thread, the thread information is printed in the run method of the thread, and the information of the two is the same.
The result is as follows:
The two threads are indeed the same thread, and it can be seen that the text in the main interface is displayed after about 5s, because the statement setContentView (R. layout. activity_main); put it behind the post startup Statement of handler, And the thread bound by handler has a latency of 5 s, so it also proves that this happens only when the same thread is used. In addition, the following logs are printed in Logcat:

09-06 17:10:19.353: I/Choreographer(19937): Skipped 62 frames!  The application may be doing too much work on its main thread.
Source code:
Package com. example. handlertest; import android. app. activity; import android. OS. bundle; import android. OS. handler; public class MainActivity extends Activity {// create a new handler private Handler handler = new Handler (); @ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); // load runnable to the handler thread queue to go to handler. post (r); // Thread t = new Thread (r); // t. start (); setContentView (R. layout. activity_main); // print activtiy thread information System. out. println ("activity_id ---->" + Thread. currentThread (). getId (); System. out. println ("activity_name ---->" + Thread. currentThread (). getName ();} Runnable r = new Runnable () {public void run () {// print the new thread information System. out. println ("handler_id ---->" + Thread. currentThread (). getId (); System. out. println ("handler_name ---->" + Thread. currentThread (). getName (); // latency of 10 s. In order to observe the time when the content in the main interface appears, try {Thread. sleep (5000);} catch (InterruptedException e) {// TODO: handle exception e. printStackTrace ();}}};}
If the statement is:
Handler. post (r );
Replace:
Thread t = new Thread (r );
T. start ();
Otherwise, the main interface content is immediately displayed when the program is running, and the system output is as follows:
Both of them indicate that the bound thread is not the same thread as the activity thread.


Handler instance 4,

In this example, we will learn how to construct a handler instead of using runnable to start a thread, instead of using the Logoff of HandlerThread. Then, the handler obtains the message, transmits the data, and then processes the message, of course this is done in another thread.
The parameters arg1 and arg2 can be used to transmit a simple integer in the message structure, or some small other data can be transmitted. You can use its Object, which can be any Object. If you want to transmit large data, you can use the setData method of the message. This method requires passing a Bundle parameter. The Bundle stores the map of the key-value pair, but its key-value type and data type are relatively fixed.

Source code:

Package com. example. handlertest; 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 MainActivity extends Activity {@ Override public void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setContentView (R. layout. activity_main); System. out. println ("activity_ID ---->" + Thread. currentThread (). getId (); // create a HanderThread object, which implements the HandlerThread handler_thread = new HandlerThread ("handler_thread"); handler_thread.start (); // The MyHandler class is a self-inherited class. Here we use the Looper of hand_thread to initialize it MyHandler my_handler = new MyHandler (handler_thread.getLooper ()); // obtain a Message msg = my_handler.obtainMessage (); // use Bundle to save data. The Bundle stores the map of the key-value pair, it's just that its key value type and data type are relatively fixed. Bundle B = new Bundle (); B. putString ("whether", "Sunday"); B. putInt ("temperature", 34); msg. setData (B); // send msg to your handler. This refers to my_handler. Call the HandleMessage method of the handler to process the mug msg. sendToTarget ();} class MyHandler extends Handler {// The empty constructor public MyHandler () {}// the function passed with the logoff type parameter. logoff is the message pump, continuously obtain and process messages from the message queue, so // each message queue has a logoff, because logoff is a encapsulated message queue and a message loop class public MyHandler (logoff lofter) {// call the constructor super (logoff) of the parent class );} @ Override public void handleMessage (Message msg) {// You Can See That Message processing is not a System executed in the main thread. out. println ("Handler_ID ---->" + Thread. currentThread (). getId (); System. out. println ("Handler_Name ---->" + Thread. currentThread (). getId (); // obtain the bundle data in the message. Bundle B = msg. getData (); String whether = B. getString ("whether"); int temperature = B. getInt ("temperature"); System. out. println ("whether =" + whether + ", temperature =" + temperature );}}}

Summary:
Handler in Android can be used to send asynchronous messages, that is, sending and receiving messages are independent of each other and can run simultaneously. In example 1 and example 2, the thread used in handler is in the same main thread as its activity, because the runnable interface called by handler directly runs the run function of this interface, rather than the start function. Example 3 specifically compares the two cases. Example 4 learn how to process messages in a new thread.


Copyright Disclaimer: This article is an original article by the blogger and cannot be reproduced without the permission of the blogger.

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.