Android基础 -- Android HandlerThread

本文介绍了Android HandlerThread的基础知识,包括它的用途、使用步骤以及与普通线程的区别。HandlerThread简化了多线程和异步消息传递的实现,源码分析揭示了其内部已封装Looper。通过实例展示了如何在工作线程中执行任务并在主线程更新UI。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.简介

AndroidThread是一个Android已经封装好的轻量级异步类,用来方便开发者更快的实现多线程、异步通信、消息传递等。

 

2.使用步骤

// 步骤1:创建HandlerThread实例对象
// 传入参数 = 线程名字,作用 = 标记该线程
   HandlerThread mHandlerThread = new HandlerThread("handlerThread");

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

// 步骤3:创建工作线程Handler & 复写handleMessage()
// 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
// 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
  Handler workHandler = new Handler( mHandlerThread.getLooper() ) {
            @Override
            public boolean handleMessage(Message msg) {
                ...//消息处理
                return true;
            }
        });

// 步骤4:使用工作线程Handler向工作线程的消息队列发送消息
// 在工作线程中,当消息循环时取出对应消息 & 在工作线程执行相关操作
  // a. 定义要发送的消息
  Message msg = Message.obtain();
  msg.what = 2; //消息的标识
  msg.obj = "B"; // 消息的存放
  // b. 通过Handler发送消息到其绑定的消息队列
  workHandler.sendMessage(msg);

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

3.与普通线程的对比

如果在Thread里使用Handler,我们要调用Looper.prepare() 和Looper.loop()

// 子线程中创建新的Handler 没有使用HandlerThread
new Thread () {
    @Override
    public void run() {
        Looper.prepare();
        Hnadler handler = new Handler();
        Looper.loop();
    } 
}

而在handlerThread中并没有调用,是因为HandlerThread已经为我们封装好了

HandlerThread源码的run方法

    @Override
    public void run() {
        // 1. 获得当前线程的id
        mTid = Process.myTid();

        // 2. 创建1个Looper对象 & MessageQueue对象
        Looper.prepare();

        // 3. 通过持有锁机制来获得当前线程的Looper对象
        synchronized (this) {
            mLooper = Looper.myLooper();
           
            // 发出通知:当前线程已经创建mLooper对象成功
            // 此处主要是通知getLooper()中的wait()
            notifyAll();
            
            // 此处使用持有锁机制 + notifyAll() 是为了保证后面获得Looper对象前就已创建好Looper对象
        }

        // 4. 设置当前线程的优先级
        Process.setThreadPriority(mPriority);

        // 5. 在线程循环前做一些准备工作 ->>分析1
        // 该方法实现体是空的,子类可实现 / 不实现该方法
        onLooperPrepared();

        // 6. 进行消息循环,即不断从MessageQueue中取消息 & 派发消息
        Looper.loop();

        mTid = -1;
    }

 

4.具体应用

创建两个Button,分别在工作线程中发送两条不同的消息(实际应用中可能是做了些复杂耗时的操作),然后再主线程中刷新UI(此处用Toast替代)

public class HandlerThreadActivity extends AppCompatActivity {

    private Handler mainHandler, workHandler;
    private HandlerThread mHandlerThread;
    private AppCompatButton mFirstBtn, mSecondBtn;

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

        initView();
        initHandlerThread();
        initHandler();
    }

    private void initView() {
        mFirstBtn = findViewById(R.id.first_btn);
        mSecondBtn = findViewById(R.id.second_btn);
    }

    private void initHandlerThread() {
        mHandlerThread = new HandlerThread("GoodLuck");
        mHandlerThread.start();
    }

    private void initHandler() {
        //和主线程关联的handler
        mainHandler = new Handler();

        //工作线程Handler

        //作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
        // 消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
        workHandler = new Handler(mHandlerThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case 1: {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(HandlerThreadActivity.this, "我是button1的消息", Toast.LENGTH_SHORT).show();
                            }
                        });

                        break;
                    }
                    case 2: {
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                Toast.makeText(HandlerThreadActivity.this, "我是button2的消息", Toast.LENGTH_SHORT).show();
                            }
                        });
                        break;
                    }
                }
            }
        };

        mFirstBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = Message.obtain();
                message.what = 1;
                workHandler.sendMessage(message);
            }
        });

        mSecondBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Message message = Message.obtain();
                message.what = 2;
                workHandler.sendMessage(message);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mHandlerThread.quit();
    }
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">

    <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/first_btn"
            android:layout_width="match_parent"
            android:text="firstBtn"
            android:layout_height="48dp"/>

    <androidx.appcompat.widget.AppCompatButton
            android:id="@+id/second_btn"
            android:text="SecondBtn"
            android:layout_width="match_parent"
            android:layout_height="48dp"/>

</LinearLayout>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值