android HandlerThread相关内容

1、在子线程中,如果要使用Handler,则先调用Looper.prepare() 为线程开启一个消息循环,最后再调用loop() 方法使之处理信息,直到循环结束。

主线程的话,主线程系统会自动为其创建Looper对象,开启消息循环。

Looper对象通过MessageQueue来存放消息和事件。一个线程只能有一个Looper,对应一个MessageQueue。 然后通过Looper.loop() 让Looper开始工作,从消息队列里取消息,处理消息。

写在Looper.loop()之后的代码不会被执行,这个函数内部应该是一个循环,当调用mHandler.getLooper().quit()后,loop才会中止,其后的代码才能得以运行。

例:

class MyThread1 extends Thread {

        @Override

        public void run() {

            super.run();

            Looper.prepare();//有该函数,下面的Handler才会起作用,否则下面的Handler不会工作

            handler1 = new Handler(){

                @Override

                public void handleMessage(Message msg) {

                    super.handleMessage(msg);

                    System.out.println( "threadName--" + Thread.currentThread().getName() + "messageWhat-"+ msg.what );

                }

            };

            handler2.sendEmptyMessage( 2 ) ;

            Looper.loop(); //处理事件

        }

    }

 

 class MyThread2 extends Thread {

        @Override

        public void run() {

            super.run();

            Looper.prepare();//有该函数,下面的Handler才会起作用,否则下面的Handler不会工作

            handler2 = new Handler(){

                @Override

                public void handleMessage(Message msg) {

                    super.handleMessage(msg);

                    System.out.println( "threadName--" + Thread.currentThread().getName() + "messageWhat-"+ msg.what );

                }

            };

            handler1.sendEmptyMessage( 5 ) ;

            Looper.loop();

        }

    }

 

以上函数,先执行 handler2.sendEmptyMessage( 2 ) ;最后执行 handler1.sendEmptyMessage( 5 ) ;因为有Looper.prepare(),Handler才会起作用。

2、Handler有几个构造重载,如果构造时没有提供Looper类对象参数,会获取当前线程的Looper对象,即将当前线程的消息循环作为Handler关联的消息循环。

3.消息处理机制中,消息存放在一个消息队列中,而线程围绕这个队列进入一个无限循环,直到程序退出。  如果队列中有消息,线程就会把消息取出来,并分发给相应的Handler进行处理;如果队列中没有消息,线程就会进入空闲等待状态,等待下一个消息的到来。

 

以上,对照看HandlerThread。

子线程处理,不需要写Looper.prepare()之类的。是一个内部建立了Looper的普通Thread。

HandlerThread将loop转到子线程中处理,分担MainLooper的工作量,降低了主线程的压力,使主界面更流畅。

开启一个线程起到多个线程的作用。处理任务是串行执行,按消息发送顺序进行处理。HandlerThread本质是一个线程,在线程内部,代码是串行处理的。

但是由于每一个任务都将以队列的方式逐个被执行到,一旦队列中有某个任务执行时间过长,那么就会导致后续的任务都会被延迟处理。

HandlerThread拥有自己的消息队列,它不会干扰或阻塞UI线程。

对于网络IO操作,HandlerThread并不适合,因为它只有一个线程,还得排队一个一个等着。

用法:

1.先创建HandlerThread的对象:mThread = new HandlerThread("handler_thread");

2.再启动该线程:mThread.start();

3.创建运行在该线程中的Hadnler:

mHander = new Handler(mThread.getLooper()){

                     handlerMessage(){

                    ..............................

                         }

};

5.如何退出该循环:用Looper的quit方法或quitSafely方法

Looper的quit方法时,实际上执行MessageQueue中的removeAllMessagesLocked方法,该方法的作用是把MessageQueue消息池中所有的消息全部清空,无论是延迟消息(延迟消息是指通过sendMessageDelayed或通过postDelayed等方法发送的需要延迟执行的消息)还是非延迟消息。

Looper的quitSafely方法时,实际上执行了MessageQueue中的removeAllFutureMessagesLocked方法,通过名字就可以看出,该方法只会清空MessageQueue消息池中所有的延迟消息,并将消息池中所有的非延迟消息派发出去让Handler去处理,quitSafely相比于quit方法安全之处在于清空消息之前会派发所有的非延迟消息。

无论是调用了quit方法还是quitSafely方法只会,Looper就不再接收新的消息。即在调用了Looper的quit或quitSafely方法之后,消息循环就终结了,这时候再通过Handler调用sendMessage或post等方法发送消息时均返回false,表示消息没有成功放入消息队列MessageQueue中,因为消息队列已经退出了。

需要注意的是Looper的quit方法从API Level 1就存在了,但是Looper的quitSafely方法从API Level 18才添加进来。

 

参考文章:

https://www.cnblogs.com/zhaoyanjun/p/5546843.html

https://www.cnblogs.com/zhaoyanjun/p/6062880.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值