Handler、AsyncTask(知识整理)

一、什么是handler
android消息机制的上层接口。
handler通过发送和处理Message和Runnable对象来关联对应线程的MessageQuene。
1.可以让对应的Message和Runnable在未来的某个时间点进行相应处理。
2.把耗时操作放在子线程中,让更新ui的操作放在主线程中。
二、handler的用法
handler有两种使用方法:
1.post(Runnable)
2.sendMessage(message)
当在主线程声明handler时(成员变量),handler是绑定在主线程中的,这样是线程安全的,如果在内部类中声明,会导致线程不安全,抛出异常。
不支持子线程中直接使用handler!!!!!
原因如下:
handler需要一个MessageQuene消息队列来保存所发送的消息,子线程默认是不开启looper轮询器的,而MessageQuene又需要looper来管理,故会抛出异常。
如果想在子线程中使用handler,那就必须自己初始化一个looper,然后再通过looper.loops方法开启一个循环。

(代码规范:
执行一个耗时操作:
在onclick方法中声明一个Thread,调用其start()方法。
在Thread中,进行耗时操作后,声明一个runnable,,然后调用handler.post方法。
这样看起来贼舒服。

这里写图片描述
post其底层仍旧是sendMessage方法(看源码!)。
三、handler机制的原理
Looper:通过prepare()创造looper,一个线程中只能有一个looper;通过Looper.loop()开启循环,实际上loop方法就是创建个死循环,不断从消息队列中取出消息进行处理。
四、handler引起的内存泄漏以及解决方法
原因:静态内部类持有外部类的匿名引用,导致外部activity无法释放。
解决方法:
1.设置handler为静态内存,也就是声明的时候加上static修饰。
2.在activity的ondestroy方法中调用 mHandler.removeCallback();
3.handler内部持有外部activity的弱引用。


AsyncTask
一、什么是AsyncTask
本质上就是一个封装了线程池和handler的异步框架。
AsyncTask适用于短时间的耗时操作,耗时很长的还是要用线程池来做。
二、AsyncTask的使用方法
1.三个参数
Integer、String等,(传参)
Integer,(进度)
String,Integer等,(返回)
2.五个方法
①onPreExecute:
执行异步任务之前的相关处理
②doInBackground:
执行耗时操作,返回值传递到onPostExecute
③onProgressUpdate:
在doInBackground里调用publishProgress(int);方法之后就会被调用,给progressbar设置进度等
④publishProgress:
在doInBackground里调用,更新进度。
⑤onPostExecute:
返回值
三、AsyncTask的机制原理
1、AsyncTask的本质是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些异步任务都是提交到静态的线程池中执行。
2、线程池中的工作线程执行doInBackground(mParams)方法执行异步任务。
3、当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler相应这些消息,并调用相关的回调函数。
四、AsyncTask注意事项
1.AsyncTask和handler都会有内存泄漏,原理都是非静态内部类持有外部类的匿名引用。当Activity销毁时,如果AsyncTask还在doinbackground里执行后台任务,因为持有activity,导致activity不能被回收,就会导致内存泄漏。所以,需要在activity的ondestroy方法里调用asyncTask的cancel方法。不调用cancel方法就会导致asyncTask不会被销毁。
2.asyncTask结果丢失,由于activity旋转或者内存不足导致被杀死的时候就会导致结果丢失。

猜你喜欢

转载自blog.csdn.net/qq_24820437/article/details/82120935