HandlerThread使用-Android

42 篇文章 2 订阅

handlerThread是内部有一个looper轮询器的Thread线程。HandlerThread,是一个具有Looper的线程,这个Looper可以用于创建Handler;另外start()必须执行,因为Handler毕竟是个Thread,调用start()会走到run()中,而HandlerThread恰恰是在run中创建的Looper。

HandlerThread产生的背景:
google为了避免以下几种情况,给android开发者提供了这样一个异步框架:

  1. 在需要做子线程耗时操作时,我们有可能会new Thread来进行
  2. 频繁多次创建子线程,对性能是有影响的
  3. 可以自己在子线程中使用looper轮询,避免多次创建线程

HandlerThread特点:

  1. HandlerThread是一个线程类,它继承了Thread
  2. 它的内部有自己的Looper对象,可以进行loop轮询
  3. 使用HandlerThread的looper创建的Handler在handleMessage中可以进行耗时操作,因为它是执行在子线程的
  4. 它的优点是不会阻塞主线程,缺点是不能同时执行多任务,需要有序执行,执行效率低。

HandlerThread其实就是一个线程;HandlerThread比较适用于单线程+异步队列的场景,比如IO读写操作数据库、文件等,耗时不多而且也不会产生较大的阻塞。对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。

适用于子线程多任务的工作场景。如:在工作线程中进行多个网络请求,多个I/O操作,最典型的应用就是 IntentService

HandlerThread的本质:继承Thread类 + 封装Handler类 + Looper()

一、用法

  1. 在主线程中新建一个 HandlerThread 对象,然后调用 start() 方法启动该线程。
  2. 创建一个主线程Handler 对象,关联APP主Looper对象,用于子线程与主线程之间的沟通。
  3. 创建一个工作线程Handler 对象,关联 HandlerThread 的 Looper 对象。
  4. 发送消息给工作线程,工作线程Handler 接收消息,并处理消息,然后调用主线程。Handler,发送信息给主线程,通知主线程做UI工作。
  5. 当对应的 Activity 销毁时,退出 HandlerThread,终止消息循环。
// 步骤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(  msg) {
                ...//消息处理
                return true;
            }
        });

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

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

二、下载示例

activity_handler_thread.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".HandlerThreadDemo.HandlerThreadActivity">

    <Button
        android:id="@+id/bt_start_download"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始下载"
        android:textSize="22sp"

        />
</RelativeLayout>

HandlerThreadActivityTwo.java

public class HandlerThreadActivityTwo extends AppCompatActivity {
    private static final String TAG = "HandlerThreadActivityTwo";
    private Handler handler;
    private HandlerThread handlerThread;
    private Button bt_start_download;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_handler_thread);
        bt_start_download = (Button) findViewById(R.id.bt_start_download);
        bt_start_download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //开启下载线程
                Handler dowmhandler = DownloadHandler();
                if(dowmhandler != null){
                    dowmhandler.post(new DownloadThread(100));
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }

    ///开启一个下载任务
    private Handler DownloadHandler(){
        if(handler == null){
            // 步骤1:创建HandlerThread实例对象
            // 传入参数 = 线程名字,作用 = 标记该线程
            handlerThread = new HandlerThread("download");
            // 步骤2:启动线程
            handlerThread.start();
            // 步骤3:创建工作线程Handler & 复写handleMessage()
            // 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
            // 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
            handler = new Handler(handlerThread.getLooper());
        }
        return handler;
    }

    //开启下载进度线程
    private class DownloadThread implements Runnable{
        private int start = 0;
        private int progres;

        public DownloadThread(int progres) {
            this.progres = progres;
        }

        @Override
        public void run() {
            while(start <= progres){
                Log.i("下载进度", ": "+start);
                start += 10;
            }
        }
    }
}

在这里插入图片描述

三、多任务使用

activity_handler_thread.xml

    <Button
        android:id="@+id/bt_more_start_download"
        android:layout_below="@id/bt_quit_download"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始多下载"
        android:textSize="22sp"
        />

    <Button
        android:id="@+id/bt_more_quit_download"
        android:layout_below="@id/bt_more_start_download"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="退出多下载"
        android:textSize="22sp"
        />

HandlerThreadActivityTwo.java

bt_more_start_download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                Handler dowmhandler = MultDownloadHandler();
                //任务1
                // 通过sendMessage()发送
                // a. 定义要发送的消息
                Message msg = Message.obtain();
                msg.what = 2; //消息的标识
                msg.obj = "A"; // 消息的存放
                // b. 通过Handler发送消息到其绑定的消息队列
                dowmhandler.sendMessage(msg);
                //延时发送
                try {
                    //延时操作
                    Thread.sleep(2000);
                    Log.i("TAG", "延时发送");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                //任务2
                // 通过sendMessage()发送
                // a. 定义要发送的消息
                Message msg2 = Message.obtain();
                msg2.what = 1; //消息的标识
                msg2.obj = "B"; // 消息的存放
                // b. 通过Handler发送消息到其绑定的消息队列
                dowmhandler.sendMessage(msg2);


            }
        });

        bt_more_quit_download.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                handlerThread.quit();
                Log.i("TAG", "退出成功");
                bt_more_quit_download.setText("多下载退出成功");
            }
        });


	///开启多个下载任务
    private Handler MultDownloadHandler(){
        if(handler == null){
            // 步骤1:创建HandlerThread实例对象
            // 传入参数 = 线程名字,作用 = 标记该线程
            handlerThread = new HandlerThread("multdownload");
            // 步骤2:启动线程
            handlerThread.start();
            // 步骤3:创建工作线程Handler & 复写handleMessage()
            // 作用:关联HandlerThread的Looper对象、实现消息处理操作 & 与其他线程进行通信
            // 注:消息处理操作(HandlerMessage())的执行线程 = mHandlerThread所创建的工作线程中执行
            handler = new Handler(handlerThread.getLooper()){
                @Override
                public void handleMessage(@NonNull Message msg) {
                    switch (msg.what){
                        case 1:
                            Log.i("TAG", "1任务开始下载 ");
                            break;
                        case 2:
                            Log.i("TAG", "2任务开始下载 ");
                            break;
                        default:
                            break;
                    }
                }
            };
        }
        return handler;
    }

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值