Android异步消息处理机制学习笔记

(一)Handler

什么是Handler

  1. Android消息机制的上层接口,Handler通过发送和处理Message和Runnable对象来关联相对应线程的MessageQueeu.
  2. 可以让对应的Message和Runable在未来的某个时间点进行相应处理;
  3. 让自己想要处理的耗时操作放在子线程,让更新UI的操作放在主线程。

Handler的使用方法

  1. post(runnable):实际也是调用sendMessage
  2. sendMessage(message)

Handler机制原理

原理

  1. Looper通过loop方法轮询MessageQueue消息,把消息发送给Handler处理;
  2. MessageQueue消息队列,先进先出原则,创建Looper时MessageQueue已被创建并和Looper关联到一起;
  3. Message就是消息对象,存储在消息队列中;
  4. Handler发送消息和处理消息。要想发送消息必须有Looper(只能发送到与其相关联的MessageQueue),并且处理Looper发来的消息。

注意:

  1. ThreadLocal只限于set/get自己线程的信息,Looper保存在ThreadLocal中可以保证每个线程有自己的Looper。
  2. Looper是怎么获取的,通过ThreadLocal的get方法获取的;Looper什么时候创建存储的,也就是ThreadLocal什么时候调用了set方法呢?Looper.prepare调用时创建一个Looper对象并set在ThreadLocal中;
  3. Looper.loop创建一个死循环,不断去消息队列读取消息并进行消息分发;
  4. 每一个Handler要与主线程的消息队列关联上,所以不能在内部类创建Handler(在子线程只要主动调用Looper.prepare和Looper.loop方法也是可以使用的)。

Handler引起的内存泄漏以及解决办法

  1. 原因
    1. 内部类持有外部类的匿名引用,导致外部activity无法释放
  2. 解决方案
    1. 使用静态内部类的Handler;
    2. 在onDestroy中释放Handler;
    3. Handler内部持有外部类的弱引用。

(二)AsyncTask

什么是AsyncTask

  1. Android轻量级的异步类,它本质上就是封装了线程池和Handler的异步框架,因此可以方便的在线程间进行切换。。
  2. 只能做耗时比较短的工作。

Async的使用方法

3个参数

  1. 执行耗时任务的参数;
  2. 执行过程中主线程得到的数据;
  3. 执行结束返回的数据。

5个方法

  1. onPreExecute在主线程调用,耗时操作前做一些初始化工作;
  2. doInBackground比较重要的,做耗时操作,并将结果返回到onPostExecute方法中;
  3. onPostExecute异步线程执行完时回调;
  4. publishProgress()在doInBackground中调用,也就是onProgressUpdate的调用间隔;
  5. onProgressUpdate异步线程执行时,在主线程提供出进度。

机制原理

  1. AsyncTask的本质是一个静态的线程池,AsyncTask派生出的子类可以实现不同的异步任务,这些任务都是提交到静态的线程池中执行;
  2. 线程池中的工作线程执行doInBackground(mParams)方法执行异步任务;
  3. 当任务状态改变之后,工作线程会向UI线程发送消息,AsyncTask内部的InternalHandler相应这些消息,并调用相关的回调函数。

注意事项

  1. 内存泄漏:非静态的内部类持有Activity的引用

    1. 静态内部类;
    2. 弱引用;
    3. 在onDestroy()中cancle.
  2. 生命周期:activity被销毁时并不会主动销毁AsyncTask,需要自己调用cancle方法。

  3. 结果丢失:屏幕旋转,内存低被回收等导致AsyncTask持有的界面被重新创建,AsyncTask引用是旧的,导致界面更新失败。
  4. 并行or串行:在Android1.6之前串行,任务放在线程池顺序执行,在1.6-2.3并行,2.3之后为了系统稳定改成串行,但是也可以执行并行,需要调用executeOnExecutor即可,不建议使用并行,不稳定。

(三)HandlerThread

HandlerThread是什么

产生背景

  1. 频繁的开启和销毁Thread子线程执行任务方便但耗费系统资源。

定义

  1. 本质就是一个Thread线程类,它继承了Thread
  2. 有自己的内部looper对象,可以进行Looper循环
  3. 通过获取HandlerThread的Looper对象传递给Handler对象,可以在handleMessage方法中执行异步任务;
  4. 优点是不会有阻塞,减少了对性能的消耗;
  5. 缺点是需要等待,不能同时进行多任务处理,处理效率较低;
  6. 与线程池和并发不同,HandlerThread是一个串行队列,HandlerThread背后只有一个线程。

HandlerThread源码解析

鸿洋大神的分析

(四)IntentService

IntentService是什么

  1. 简介

    1. IntentService是继承Service并处理异步请求的一个类,在IntentService内有一个工作线程来处理耗时操作,启动IntentService的方式和启动传统的Service一样,同时,当任务执行完成后,IntentService会自动停止,而不需要我们手动或者调用stopSelf().另外,可以多次启动IntentService,但只有一个IntentService实例,而每一个耗时操作会以工作队列的方式在IntentService的onHandleIntent回调方法中执行,并且,每次只会执行一个工作线程,执行完第一个再执行第二个,直到最后一个执行完后自动销毁。
  2. IntentService是什么

    1. 它本质是一种特殊的Service,继承自Service并且本身就是一个抽象类;
    2. 它内部通过HandleThread和Handler实现异步操作。

IntentService使用

  1. 创建IntentService时只需要实现onHandleIntent和构造方法,onHandleIntent为异步方法,可以执行耗时操作。

IntentService详解

你可能感兴趣的:(面试题收集)