Android多线程-----异步(HandlerThread)

它就是一个帮我们创建 Looper 的线程,让我们可以直接在线程中使用 Handler 来处理异步任务

一、他们的区别


      ①Handler:在android中负责发送和处理消息,通过它可以实现其他支线线程与主线程之间的消息通讯。

      ②Thread:Java进程中执行运算的最小单位,亦即执行处理机调度的基本单位。某一进程中一路单独运行的程序。

      ③HandlerThread:一个继承自Thread的类HandlerThread,Android中没有对Java中的Thread进行任何封装,而是提供了一个继承自Thread的类HandlerThread类,这个类对Java的Thread做了很多便利的封装

      A:那么HandlerThread到底有什么作用,所谓的便利封装又体现在哪里?

      B:HandlerThread对象start后可以获得其Looper对象,并且使用这个Looper对象实例Handler,之后Handler就可以运行在其他线程中了。     

      C:Andriod提供了 Handler  和  Looper  来满足线程间的通信。 Handler 先进先出原则。 Looper 类用来管理特定线程内对象之间的消息交换 (MessageExchange) 。 

  D:HandlerThread最大的优势在于引入MessageQueue概念,可以进行多任务队列管理。

  E:HandlerThread背后只有一个线程,所以任务是串行依次执行的。串行相对于并行来说更安全,各任务之间不会存在多线程安全问题。

  F:HandlerThread所产生的线程会一直存活,Looper会在该线程中持续的检查MessageQueue,并开启消息处理的循环。这一点和Thread(),AsyncTask都不同,thread实例的重用可以避免线程相关的对象的频繁重建和销毁。 getLooper().quit();来退出这个线程,其实原理很简单,就是改变在消息循环里面标志位,退出整个while循环,使线程执行完毕。

1)Looper:   是android为线程间异步消息通信提供的一种机制,利用Looper机制可以方便我们实现多线程编程时线程间的相互沟通。如果不用Looper而采用其它的线程间通信方式(像管道,共享内存,消息队列等)也是一样的。Looper的实现是利用消息队列的方式,为用户封装了一层API,用户不需要考虑互斥加锁的问题,方便用户的使用。一个线程可以产生一个 Looper 对象,由它来管理此线程里的 MessageQueue( 消息队列 ) 和对消息进行循环。 

2)Handler:  你可以构造 Handler 对象来与 Looper 沟通,以便 push 新消息到 MessageQueue 里 ; 或者接收 Looper 从 Message Queue 取出 所送来的消息。 

3) Message Queue( 消息队列 ): 用来存放线程放入的消息。 

4) Message:是线程间通讯的消息载体。两个码头之间运输货物,Message充当集装箱的功能,里面可以存放任何你想传递的消息。

      看到这里就明白了为什么:如果一个线程要处理消息,那么它必须拥有自己的Looper,并不是Handler在哪里创建,就可以在哪里处理消息。

注:对应关系Thread(1):Looper(1):MessageQueen(1):Handler(n).

二、HandlerThread的使用


正如前面所说,线程间通信的时候,比如Android中常见的更新UI,涉及到的是子线程和主线程之间的通信,实现方式就是Handler+Looper,但是要自己手动操作Looper,不推荐,所以谷歌封装了HandlerThread类(类似于AsyncTask类)

那它的使用场景就是 Thread + Looper 使用场景的结合,即:在子线程中执行耗时的、可能有多个任务的操作。比如说多个网络请求操作,或者多文件 I/O 等等。使用 HandlerThread 的典型例子就是 IntentService

上代码,具体实现:

1、首先新建HandlerThread并且执行start()

private HandlerThread mHandlerThread;


mHandlerThread = new HandlerThread("HandlerThread");

handlerThread.start();

2、创建Handler,使用mHandlerThread.getLooper()生成Looper:

final Handler handler = new Handler(mHandlerThread.getLooper()){

            @Override

            public void handleMessage(Message msg) {

                System.out.println("收到消息");

            }

        };

3、mHandlerThread.getLooper().quit();


举个例子

public class MainActivity extends AppCompatActivity {

    private TextView tvMain;

    private HandlerThread mHandlerThread;
    //子线程中的handler
    private Handler mThreadHandler;
    //UI线程中的handler
    private Handler mMainHandler = new Handler();

    //以防退出界面后Handler还在执行
    private boolean isUpdateInfo;
    //用以表示该handler的常熟
    private static final int MSG_UPDATE_INFO = 0x110;

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

        tvMain = (TextView) findViewById(R.id.tv_main);

        initThread();
    }


    private void initThread()
    {
        mHandlerThread = new HandlerThread("check-message-coming");
        mHandlerThread.start();

        mThreadHandler = new Handler(mHandlerThread.getLooper())
        {
            @Override
            public void handleMessage(Message msg)
            {
                update();//模拟数据更新

                if (isUpdateInfo)
                    mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
            }
        };

    }

    private void update()
    {
        try
        {
            //模拟耗时
            Thread.sleep(2000);
            mMainHandler.post(new Runnable()
            {
                @Override
                public void run()
                {
                    String result = "每隔2秒更新一下数据:";
                    result += Math.random();
                    tvMain.setText(result);
                }
            });

        } catch (InterruptedException e)
        {
            e.printStackTrace();
        }

    }

    @Override
    protected void onResume()
    {
        super.onResume();
        //开始查询
        isUpdateInfo = true;
        mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
    }

    @Override
    protected void onPause()
    {
        super.onPause();
        //停止查询
        //以防退出界面后Handler还在执行
        isUpdateInfo = false;
        mThreadHandler.removeMessages(MSG_UPDATE_INFO);
    }

    @Override
    protected void onDestroy()
    {
        super.onDestroy();
        //释放资源
        mHandlerThread.quit();
    }
}

 

从上面代码可以看出,HandlerThread继承于Thread,所以它本质就是个Thread。与普通Thread的差别就在于,然后在内部直接实现了Looper的实现,这是Handler消息机制必不可少的。有了自己的looper,可以让我们在自己的线程中分发和处理消息。如果不用HandlerThread的话,需要手动去调用Looper.prepare()和Looper.loop()这些方法。
 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值