一、Handler

1、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

2、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

3、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

4、post(runnable)

①创建一个成员变量uiHandler,创建完成后自动绑定到了主线程

异步消息处理机制Handler、asynctask、handlerthread、intentservice


②在耗时操作执行完成之后,通知更新UI

异步消息处理机制Handler、asynctask、handlerthread、intentservice

③在源码中可以看到,底层也是调用的sendmessage方法,只是对该方法进行了封装

异步消息处理机制Handler、asynctask、handlerthread、intentservice


5、sendMessage方法

①创建handler对象,并实现方法

异步消息处理机制Handler、asynctask、handlerthread、intentservice

②发送消息

异步消息处理机制Handler、asynctask、handlerthread、intentservice


6、handler的消息机制

①handler只能发送到与之相关联的线程中,

异步消息处理机制Handler、asynctask、handlerthread、intentservice

②在构造函数中创建了looper,并通过looper创建了messagequeue,这样在构造方法当中,handler已经和looper和messagequeque进行了关联,而messageque又通过looper来管理

异步消息处理机制Handler、asynctask、handlerthread、intentservice

③looper的获取

异步消息处理机制Handler、asynctask、handlerthread、intentservice


在looper的prepareMainLooper中,调用了prepare方法

异步消息处理机制Handler、asynctask、handlerthread、intentservice


在prepare方法中创建了一个looper对象,并将它设置给了threadlocal,这样就保证了每一个线程looper的唯一性

异步消息处理机制Handler、asynctask、handlerthread、intentservice

④looper.loope()方法,实际上就是创建了一个死循环,并且不断地从队列中获取消息并处理消息的过程

dispatchMessage用于消息的分发

异步消息处理机制Handler、asynctask、handlerthread、intentservice


message中的target实际上就是一个handler

异步消息处理机制Handler、asynctask、handlerthread、intentservice

⑤对looper的总结

在handler的构造方法中创建了looper,在looper的prepare方法中创建looper并把它保存到了threadlocal中,通过looper.loop()开启循环,来进行消息的分发,最终调用了msg.target.dispatchMessage方法,实际上又把消息传递给了handler。

通过handler将消息传递给了消息队列,而消息队列又将消息分发给了handler来处理。

handler的作用:一个是接收消息与发送消息,另一个是处理消息

⑥handler的dispatch方法

实际上就是一个中转器。msg的callback实际上就是一个runnable。

不管handler以何种方式发送消息,都会通过looper不断地从消息队列中获取消息,然后交由handler.dispachMessage这个方法进行处理

异步消息处理机制Handler、asynctask、handlerthread、intentservice


handleCallback世界上就是走了callback的run方法

异步消息处理机制Handler、asynctask、handlerthread、intentservice

异步消息处理机制Handler、asynctask、handlerthread、intentservice


7、handler的内存泄漏及解决办法

异步消息处理机制Handler、asynctask、handlerthread、intentservice

②从源码中可以看到,所创建的handler不是静态内部类,所以会持有handlerwithruannableactivity这个引用,当activity要被回收的时候,由于handler可以在做耗时的操作,导致handler还没有被释放,handler所持有的activity的引用也不能被释放,导致activity没有被回收,而停留在堆内存当中,造成了内存泄漏

异步消息处理机制Handler、asynctask、handlerthread、intentservice


③解决办法:

将handler设置为静态内部类

异步消息处理机制Handler、asynctask、handlerthread、intentservice

在activity的onDestroy方法中,调用handler的removeCallback()方法

这两步就可以解决内存泄漏


二、AsyncTask

1、AsyncTask只能做一些耗时比较短的操作,如果要做一些耗时比较长的操作,还是需要使用线程池。由于集成了handler,可以很方便地在ui线程和子线程中进行切换

异步消息处理机制Handler、asynctask、handlerthread、intentservice


2、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

3、代码

异步消息处理机制Handler、asynctask、handlerthread、intentservice

②三个参数

第一个参数Integer:表示执行Asynctask时所需要执行的参数,可用于在后台执行任务时使用

第二个参数Integer表示在后台执行任务时显示当前的进度

第三个参数String表示result,在处理结果时使用

③五个方法

构造方法

onPreExecute:运行在主线程,在异步任务开始前执行

doInBackgroud:处理耗时操作,在onPreExecute执行之后执行

onProgressUpdate:在doInBackgroud方法之后执行

onPostExecute:后台计算完成之后调用

4、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

5、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

②内存泄漏:原因是非静态的内部类持有外面类的引用,在doInbackgroud方法中执行了耗时操作,从而持有activity的引用,不能被gc回收,导致的内存泄漏。解决方法:将AsyncTask设置为静态的,同时在静态的AsyncTask中持有外部activity的弱引用,让activity需要被回收的时候可以顺利被回收。同时,可以在activity的ondestroy方法中执行asynctask的cancle方法进行finish

③生命周期:asynctask并不是随着activity的销毁而销毁,因为耗时任何在doinbackgroud方法中执行,如果没有主动调用asynctask的cancel方法是不会被销毁的。这样可能会导致asynctask在activity在销毁之前崩溃。这样必须在activity的ondestroy方法中调用asynctask的cancle方法来保证程序的稳定

④结果丢失:与生命周期类似,主要是在activity旋转或activity由于内存不够被后台杀掉,导致activity被重新创建而之前创建的asynctask会持有之前的activity的引用,但是引用已经无效,此时调用asynctask的onpostexecute方法不会再生效。这就是asynctask结果丢失的原因

⑤并行或串行:在Android 1.6之前的版本,asynctask都是串行,会把所有的任务一串一串地放到线程池中有序地执行。在1.6到2.3的版本之后,改成了并行。但是在2.3之后,为了维护稳定,又改成了串行。但是还是可以执行并行,想执行并行的时候excute.onExcute()这个方法。一般建议,只使用串行,这样能保证线程池的稳定


三、HandlerThread

1、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

2、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

在子线程中不能开启handler的原因:handler的sendmessage和post(ruannable)都需要一个消息队列来保存它所发送的消息,而子线程中默认是没有开启looper轮询器的,而消息队列又是由looper进行管理的。所以,在子线程如果想创建一个handler发生消息,是没有关联的messagequeue来存储消息,所以会抛出异常。如果想在子线程中创建一个handler,必须自己初始化一个looper,然后再通过looper.loops()开启一个循环,才能创建handler

3、

异步消息处理机制Handler、asynctask、handlerthread、intentservice

4、源码

①继承了thread,onLooperPrepared()方法必须在开启looper.loop()之前调用

异步消息处理机制Handler、asynctask、handlerthread、intentservice

②run方法是每一个thread都必须复写的一个方法

异步消息处理机制Handler、asynctask、handlerthread、intentservice

Looper.prepare():初始化一个looper

onLooperPrepared():自己重写

Looper.loop():开启循环

③getLooper()

异步消息处理机制Handler、asynctask、handlerthread、intentservice

以阻塞等待的方式进行创建

quit和quitsafely都是使looper退出消息队列,但是quitesafely更加安全,但是效率不高

异步消息处理机制Handler、asynctask、handlerthread、intentservice



四、IntentService

1、继承service,比service优先级高,串行执行

异步消息处理机制Handler、asynctask、handlerthread、intentservice


异步消息处理机制Handler、asynctask、handlerthread、intentservice


2、使用方法

异步消息处理机制Handler、asynctask、handlerthread、intentservice

①创建一个类集成intentservice

构造方法和onHandleIntent必须实现

异步消息处理机制Handler、asynctask、handlerthread、intentservice


异步消息处理机制Handler、asynctask、handlerthread、intentservice




②最后,通过handler更新ui

异步消息处理机制Handler、asynctask、handlerthread、intentservice


③开启intentservice,虽然开启了多次,但是实例只有一个

异步消息处理机制Handler、asynctask、handlerthread、intentservice


3、

intentservice的源码

①继承自service

异步消息处理机制Handler、asynctask、handlerthread、intentservice


HanderThread:在onCreate()方法中,创建了一个HandlerThread,说明内部就是使用handlerthread进行消息传递的

ServiceHandler:继承了handler的handler

Looper:传入了handlerthread的looper对象

异步消息处理机制Handler、asynctask、handlerthread、intentservice

intentservice启动后会调用onStartCommand方法,这个方法里只是调用了一个onStart()方法

异步消息处理机制Handler、asynctask、handlerthread、intentservice

④onStart()方法通过sendMessage()方法传递了一个消息

异步消息处理机制Handler、asynctask、handlerthread、intentservice

⑤servicehandler的handmessage方法

实际上调用了handlerservice的handmessage方法,方法结束后停止了服务,stopself()方法中传入了参数,因为如果不传入参数,会立即终止,如果传入了参数,会等待所有的参数都执行完后再终止

异步消息处理机制Handler、asynctask、handlerthread、intentservice

⑥handleMessage中会回调onHandleIntent方法,该方法是一个抽象方法,该方法执行的是异步任务,是一个异步方法,原因是有一个servicehandler方法是处理异步任务的。当handlerintent方法执行完毕后,intentservice会立即销毁,但是如果里面有很多任务的话,会等待最后一个任务执行完后再销毁


异步消息处理机制Handler、asynctask、handlerthread、intentservice


异步消息处理机制Handler、asynctask、handlerthread、intentservice






注:

1、参考资料:https://coding.imooc.com/lesson/101.html#mid=3575

相关文章:

  • 2022-12-23
  • 2021-09-09
  • 2022-02-08
  • 2021-10-11
  • 2022-01-10
  • 2022-01-12
  • 2022-02-08
猜你喜欢
  • 2021-10-18
  • 2021-05-30
  • 2021-07-24
  • 2021-12-01
  • 2021-07-27
  • 2021-06-14
  • 2021-07-20
相关资源
相似解决方案