Android

多线程—HandlerThread

2020-02-10  本文已影响0人  似焰如火

1. 简单说明

2. 使用步骤

// 第1步:先创建HandlerThread对象
// 传入参数即线程名字,用于标记该线程
   HandlerThread mHandlerThread = new HandlerThread("handlerThread");

// 步骤2:启动线程
   mHandlerThread.start();

// 步骤3:给工作线程创建Handler 并重写handleMessage()方法
// 创建Handler时,要关联HandlerThread的Looper对象,此时消息处理操作的执行线程就是 mHandlerThread所创建的工作线程。必须保证这个工作线程已经start,否则还没有Looper对象。
  Handler workHandler = new Handler( mHandlerThread.getLooper() ) {
            @Override
            public void handleMessage(Message msg) {
                ...//消息处理
            }
        });

// 步骤4:在主线程中使用给工作线程创建的workHandler ,向工作线程的消息队列发送消息
  // a. 定义要发送的消息
  Message msg = Message.obtain();
  msg.what = 2; //消息的标识
  msg.obj = "B"; // 消息的存放
  // b. 通过Handler发送消息到其绑定的消息队列
  workHandler.sendMessage(msg);

// 步骤5:结束线程,即停止线程的消息循环
  mHandlerThread.quit();

3. 举个例子

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.47"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.313" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="600dp"
        android:layout_marginEnd="10dp"
        app:layout_constraintBottom_toTopOf="@+id/show"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">


        <Button
            android:id="@+id/bt0"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="start" />

        <Button
            android:id="@+id/bt1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="delay 1s" />

        <Button
            android:id="@+id/bt2"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="delay 3s" />

        <Button
            android:id="@+id/bt3"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="stop" />
    </LinearLayout>


</androidx.constraintlayout.widget.ConstraintLayout>
public class MainActivity extends AppCompatActivity {

    Handler mainhandler,workhandler;
    boolean flag_start =false;
    HandlerThread mHandlerThread;
    protected TextView show;
    Button bt0,bt1,bt2,bt3;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        show = findViewById(R.id.show);
        bt0 = findViewById(R.id.bt0);
        bt1 = findViewById(R.id.bt1);
        bt2 = findViewById(R.id.bt2);
        bt3 = findViewById(R.id.bt3);

        bt0.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                flag_start = true;
                show.setText("开始");
                mHandlerThread = new HandlerThread("myHandlerThread");
                mHandlerThread.start();
                mainhandler = new Handler();
                workhandler = new Handler(mHandlerThread.getLooper()) {
                    @Override
                    public void handleMessage(Message msg) {
                        switch (msg.what){
                            case 1:
                                try {Thread.sleep(1000);} catch (InterruptedException e) {}
                                mainhandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        show.setText("延时1秒");
                                    }
                                });
                                break;
                            case 2:
                                try {Thread.sleep(3000);} catch (InterruptedException e) {}
                                mainhandler.post(new Runnable() {
                                    @Override
                                    public void run() {
                                        show.setText("延时3秒");
                                    }
                                });
                                break;
                            default:
                                Log.d("HandlerThreadTest","message error");
                                break;
                        }
                    }
                };
            }
        });
        bt1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(flag_start == true){
                    Message msg = Message.obtain();
                    msg.what = 1;
                    workhandler.sendMessage(msg);
                }
            }
        });
        bt2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if(flag_start == true){
                    Message msg = Message.obtain();
                    msg.what = 2;
                    workhandler.sendMessage(msg);
                }
            }
        });
        bt3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                flag_start = false;
                mHandlerThread.quit();
                show.setText("停止");
            }
        });
    }
}

  1. 在主线程中定义了Handler, 实现了handleMessage()方法, 在其它线程调用sendMessage后, looper中的MessageQueue会收到该Message, 但如果此时主线程正忙, 该消息不会被处理. 当主线程空闲时, Looper才会去查看MessageQueue中的消息, 并调用handleMessage进行处理.
上一篇 下一篇

猜你喜欢

热点阅读