android development tutorial handle implements multithreading and asynchronous processing

  • 2020-05-24 06:10:59
  • OfStack

This is a brief discussion of Handler. Why does Handler appear? First, before the basic controls that are basic in Activity onCreate (Bundle savedInstanceState) method calls and handle, however, in some cases, such as on the Internet to download software such as 1, some need to wait for a response operation with longer time, if the method in the Activity same words, so in the implementation of this method, the whole Activity is immobile, the user can only wait for, so that the user experience is 10 points, with poor results of this approach and the best is wait for a period of time, to get the desired results, In order to avoid this situation, the feature of Handler, which is like a thread queue, is introduced. It is also a kind of asynchronous message processing.

First of all, let's take a look at an example to understand Handler.

In the layout file are two buttons, start and stop, that 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 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); 
        } 
    }; 
} 

As you can see, in Activity, an event listener is bound to the two buttons, an instance of Handler is created, and an anonymous inner class is created, which is an HandlerThread thread that implements the Runnable interface.

When the start button is pressed, handler.post (HandlerThread) is executed; This one, as I said earlier, Handler USES a thread queue, so this is just adding HandlerThread to the handler thread queue, because HandlerThread is the first thread, so it will immediately execute its run() method. In the run() method, handler. postDelayed(HandlerThread, 3000); Once again, HandlerThread is put into the handler thread queue, with 3000ms's latency set. In this way, the whole program will run continuously and print "HandlerThread is Running... "in LogCat every 3000ms. .

It's important to note, however, that you don't think that handler now separates the thread from the main thread, because there are no two threads running, and the printed content is also from the main thread. We can do an experiment where we print the current Thread name by Thread.currentThread.getName () after the onCreate function and where we print the statement, and you can see that it's all the same, main, which means it's all coming from the main thread. We know that the start() method is needed to start a thread, but instead of start for HandlerThread, run() method is directly called in this program. No wonder it's just the main thread running.

From the above example, this Handler is not what we want it to be, because it is not asynchronous and still runs on one main thread.

Therefore, we must use Handler in another way.
To implement the asynchronous multithreading of Handler, you need to understand two other classes, one is the Message class and the other is the Looper class.
Each Handler object has a message queue, which is the stored Message object. You can use obtainMessage() to get the message object. At the same time, Message object is used to transfer using, it can deliver two integer and a Object, try to use Message arg1 and arg2 two integer to pass parameters, it said (API) of minimum consumption of the system, if pass data quantity is large, you can use setData (Bundle a) method, the Bundle object can be rough as 1 Map object, but its Key are String, and 1 some type value is limited, You can check it in API.

The Looper class has the ability to get messages from the message queue in a loop. We can use Looper in a thread, so that the thread can loop to get messages from the message queue until the message queue is empty. However, we do not directly create and use Looper, but HandlerThread class provided by Android implements Looper, so we only need to use HandlerThread class, we use HandlerThread object to call getLooper() to get the Looper object of this thread.

Let's look at the following example


import android.app.Activity; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.HandlerThread; 
import android.os.Looper; 
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 1 a HandlerThread Object, it is 1 A thread  
        handlerThread.start();// Starting a thread  

        MyHandler myHandler = new MyHandler(handlerThread.getLooper());// create 1 a MyHandler Object, which inherits Handler From the bottom MyHandler As you can see in the class, it's called Handler Of the parent class Handler(Looper looper) I passed it in here Looper Object from HandlerThread Obtained in.  
        Message msg = myHandler.obtainMessage();// Get the message object  
        msg.sendToTarget();// The resulting message object is sent to the generated message Handler , i.e., myHandler when myHandler When a message is received, it is invoked handleMessage Method to process the message  
    } 

    class MyHandler extends Handler{ 
        public MyHandler() {// The constructor  
            // TODO Auto-generated constructor stub 
        } 

        public MyHandler(Looper looper){// The constructor  
            super(looper);// Implements the constructor for the parent class  
        } 

        @Override 
        public void handleMessage(Message msg) {// When the Handler To receive Message Object, it will automatically call this method to correct Message Object processing  
            // TODO Auto-generated method stub 
            System.out.println("Handler---->"+Thread.currentThread().getName()); 
        } 
    } 
} 

The above code is in LogCat, System. The execution result of out is:
Acitivity---- > main
Handler---- > HandlerThread
This shows that using Handler, combined with Looper and Message, can achieve the separation from the main thread, so as to achieve multithreading and asynchronous processing.


Related articles: