Detailed communication between Android neutron and UI threads

  • 2020-06-23 01:56:29
  • OfStack

Detailed explanation of communication between Android neutron and UI threads

1. In multithreaded programming, we often use Handler, Thread and Runnable. Now let's explain 1 in detail.
2. First of all, the principles of single-threaded model must be followed when developing Android applications:
Android UI operations are not thread-safe and must be performed within the UI thread.
3.Handler:
(1) concept:
Handler is the bridge between Activity and Thread/runnable. Handler, on the other hand, runs in the main UI thread, which, along with its children, can pass data through the Message object.
(2). Use:
A: Handler runs in THE UI thread. It mainly receives data information sent by the child thread and updates UI with this data in coordination with the main thread to interact with UI main thread. For example, you can send an message using handler and then receive and process the message in the thread of handler.
B: Message handler. With Handler object, we can encapsulate Message object, and then add Message object to MessageQueue through sendMessage(msg). When MessageQueue loops to the Message, it is processed by calling the handleMessage() method of the corresponding handler object of the Message object.
C: Handler can distribute Runnable objects or Message objects.

4. Message:
Message objects, as the name implies, are classes that record message information. That is to say, the carrier of information, the storage of information content. This class has several important fields:

(1).arg1 and arg2: We can use two fields to store the integer value we need to pass. In Service, we can use them to store ID of Service.
(2).obj: This field is of type Object and we can have it pass an object to the recipient of a message.
(3).what: This field can be said to be the flag of the message to determine which message was received. In message processing, we can do different things based on the different values of this field, similar to how we can determine which button was clicked by switch(v.getId ()) when processing Button events.
Android recommends obtaining Message objects either through Message.obtain () or Handler.obtainMessage (). This is not necessarily to create a new instance directly, but to see if there are any Message instances available from the message pool, and to retrieve and return the instance if there are any. Conversely, if there are no instances of Message available in the message pool, a new Message object is created based on the given parameter new1. By default, the Android system instantiates 10 Message objects in the message pool.
5. Source code display:
(1). activity_main.xml layout file:


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:tools="http://schemas.android.com/tools"
  android:id="@+id/container"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:orientation="vertical" >

  <Button
    android:id="@+id/btn"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=" The custom Thread inheritance Thread" />


  <Button
    android:id="@+id/btn2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=" The custom Runnable implementation Runnable" />


  <Button
    android:id="@+id/btn3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=" Regularly update UI Interface, Handler distribution Runnable object " />


  <Button
    android:id="@+id/btn4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text=" Regularly update UI Interface, Handler distribution Message object " />

  <TextView
    android:id="@+id/tv"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="0" />

</LinearLayout>

(2).MainActivity.java


package com.chengdong.su.threaddemo;

import com.chengdong.su.threaddemo.util.MyRunnable;
import com.chengdong.su.threaddemo.util.MyThread;

import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends Activity implements OnClickListener {
  /** TAG */
  private final String TAG = getClass().getSimpleName();
  /** the object of the button */
  private Button mButton;
  /** the object of the button */
  private Button mButton2;
  /** the object of the button */
  private Button mButton3;
  /** the object of the button */
  private Button mButton4;
  /** the object of the TextView */
  private TextView mTextView;
  /**  count  */
  private int mCount = 0;
  /**  mark  */
  private int MESSAGE_FLAG = 1;

  /**
   * Handler distribution Runnable Method of object 
   */
  private Handler mHandler = new Handler();

  Runnable runnable = new Runnable() {

    @Override
    public void run() {
      mCount++;
      mHandler.postDelayed(runnable, 1000);
      mTextView.setText(mCount + "");

    }
  };
  /***
   * Handler distribution Message Method of object 
   */

  Handler mHandler2 = new Handler() {
    public void handleMessage(android.os.Message msg) {
      if (msg.what == 1) {

        mTextView.setText("Handler distribution Message Method of object ");
      }
    }
  };

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initView();

  }

  /**
   *  Initializes the component object 
   */
  private void initView() {
    mButton = (Button) findViewById(R.id.btn);
    mButton2 = (Button) findViewById(R.id.btn2);
    mButton3 = (Button) findViewById(R.id.btn3);
    mButton4 = (Button) findViewById(R.id.btn4);

    mButton.setOnClickListener(this);
    mButton2.setOnClickListener(this);
    mButton3.setOnClickListener(this);
    mButton4.setOnClickListener(this);

    mTextView = (TextView) findViewById(R.id.tv);

  }

  @Override
  public void onClick(View v) {
    switch (v.getId()) {
    case R.id.btn: {
      //  methods 1 : How to inherit: Custom Thread inheritance Thread, open 1 A new thread 
      new MyThread().start();
      break;
    }
    case R.id.btn2: {
      //  methods 2 : Implementation method: implement Runnable
      new Thread(new MyRunnable()).start();
      break;
    }
    //  methods 3 : handler distribution Runnable Object: Periodic updates UI interface   Submit your plan and execute it immediately 
    case R.id.btn3: {

      // Handler distribution Runnable object 
      mHandler.post(runnable);
      break;
    }
    //  methods 4 : Handler distribution Message object   , update regularly UI interface   Submit your plan and execute it immediately 
    case R.id.btn4: {

      //  This is not recommended 
      // Message msg = new Message();
      //  It is recommended to use this method of getting objects: getting the available ones from the message pool Message object 
      Message msg = Message.obtain();
      msg.what = MESSAGE_FLAG;
      mHandler2.sendMessage(msg);
      break;
    }

    default:
      break;
    }

  }
}

(3).MyRunnable.java


package com.chengdong.su.threaddemo.util;

import android.util.Log;

/***
 *  The custom 1 a MyRunnable thread 
 * 
 * @author scd
 * 
 */
public class MyRunnable implements Runnable {

  public MyRunnable() {
    super();
  }

  /** TAG */
  private final String TAG = getClass().getSimpleName();

  @Override
  public void run() {
    for (int i = 0; i < 20; i++) {
      Log.e(TAG, Thread.currentThread().getName() + ", Method of implementation " + i);

    }

  }

}

(4)MyThread.java


package com.chengdong.su.threaddemo.util;

import android.util.Log;

/***
 *  The custom 1 A thread 
 * 
 * @author scd
 * 
 */
public class MyThread extends Thread {

  public MyThread() {
    super();
  }

  /** TAG */
  private final String TAG = getClass().getSimpleName();

  @Override
  public void run() {
    super.run();
    for (int i = 0; i < 10; i++) {
      Log.e(TAG, Thread.currentThread().getName() + ", inheritance Thread Class: " + i);

    }
  }

}


Related articles: