Android线程相关_Handler_Message_AsyncTask

ANR

============================
  * Application Not Responding
  * 触碰屏幕5秒无响应时弹出
  * 屏幕刷新与事件监听器代码,在同一个线程(Main线程)中执行
  * 避免 ANR
  ------------------------
    * 启动新的线程执行耗时操作,使主线程可以及时响应用户

Android 线程通信

============================
  * 生产者消费者

Android 单线程模型

============================
  * 主线程
    进入一个死循环,处理消息
    *) 主线程中存在一个 MessageQueue
    *) 主线程中存在一个 Looper,死循环从消息队列获取消息进行处理
  * 界面更新,必须在主线程中执行

Looper / MessageQueue

=========================================
  * 循环体
  * 内部包含一个 MessageQueue 消息队列
  * Looper 负责死循环从消息队列取消息,执行处理
  * 会绑定到当前线程
    主线程中,默认存在一个 Looper

Handler

=========================================
  * 向关联的 Looper 发送消息,
    Looper 在处理消息时,再发回到 Handler 处理
    创建实例
    -------------------------------------------
      1. 持有当前线程的 Looper
        Handler handler = new Handler();    
      2. 由重写的方法处理消息
        Handler handler = new Handler() {
            重写 handleMessage(Message msg)
        };  
      3. 由外接的回调对象处理消息
        Handler handler = new Handler(callback); 
      4. 持有指定线程的 Looper
        Handler handler = new Handler(t1.getLooper());
        Handler handler = new Handler(Looper.getMainLooper());
        Handler handler = new Handler(Looper.myLooper());
    方法
    -------------------------------------------
        handleMessage(Message msg)
            子类中,可重写此方法,处理消息
        
        sendMessage(Message msg)  发送消息
        sendMessageAtFrontOfQueue(Message msg)  在队列前插入消息,这个消息会被先处理
        sendMessageAtTime(Message msg, long uptimeMillis) 先缓存,定时发出
        sendMessageDelayed(Message msg, long delayMillis) 先缓存,延迟一段时间后,发出
        
        sendEmptyMessage(int what)
        sendEmptyMessageAtTime(int what, long uptimeMillis)
        sendEmptyMessageDelayed(int what, long delayMillis)       
              发送简单消息的简化方法,
              方法内部也会创建 Message 实例再发送
        
        post(Runnable r)
        postAtFrontOfQueue(Runnable r)
        postAtTime(Runnable r, Object token, long uptimeMillis)
        postAtTime(Runnable r, long uptimeMillis)
        postDelayed(Runnable r, long delayMillis) 
              post() 方法内,创建了一个 Message 对象,
              而且为 Message 对象,接入一个 callback 回调对象

        obtainMessage(int what, int arg1, int arg2)
        obtainMessage()
        obtainMessage(int what, int arg1, int arg2, Object obj)
        obtainMessage(int what)
        obtainMessage(int what, Object obj)   
            封装 Message.obtain(...)
        
        removeCallbacks(Runnable r)
        removeCallbacks(Runnable r, Object token)
        removeCallbacksAndMessages(Object token)
        removeMessages(int what)
        removeMessages(int what, Object object)
        
        hasMessages(int what, Object object)
          
        dispatchMessage(Message msg)
            
            Looper 处理消息时,调用 Handler 的dispatchMessage方法,
            此方法内的逻辑: 
                1. 存在 msg 的回调对象,执行此回调对象
                2. 在 Handler 上存在回调对象,执行此回调对象       
                      2.1. 该方法返回 true,结束
                      2.2. 该方法返回 false,执行重写的 handleMessage() 方法    
                3. 以上两个回调对象都不存在,
                   那么执行重写的 handleMessage() 方法

Message

=========================================
  * 消息
    创建实例
    ------------------------------------------------
        Message msg = new Message();
        
        Message msg = Message.obtain();
        Message msg = Message.obtain(Handler h);
        Message msg = Message.obtain(Handler h, int what);
        Message msg = Message.obtain(Handler h, int what, Object obj);
        Message msg = Message.obtain(Handler h, int what, int arg1, int arg2);
        Message msg = Message.obtain(Handler h, int what, int arg1, int arg2, Object obj);
        Message msg = Message.obtain(Handler h, Runnable callback);
        Message msg = Message.obtain(Message orig);
        
            * obtain 方法,获得缓存的 Message 对象,减少 Message 对象的创建

    属性
    -----------------------------------------------
        int     what    想干嘛
        int     arg1    自定义参数
        int     arg2    自定义参数
        Object  obj     任意对象
        
        Handler target  引用用来发送此消息的 Handler

    方法
    -----------------------------------------------
        setData(Bundle bundle)
        getData()
            Bundle 本质是哈希表,存放一组键值对数据
    
        setTarget(Handler handler)
        getTarget()
            访问关联的 Handler 对象
        
        sendToTarget()  
            使用关联的 Handler 对象,发送自身

Looper
===============================================
  * 会绑定到线程
  * loop() 方法执行一个死循环,
    从队列获取消息并处理

    Looper.prepare()        在当前线程中创建消息队列,并实例化一个新的 Looper,绑定到线程
    Looper.loop()           开始死循环轮询消息

    Looper.getMainLooper()  获得主线程(UI 线程) Looper
    Looper.myLooper()       获得当前线程 Looper

    myQueue()               获得当前线程消息队列
    setMessageLogging(Printer printer)  //LogPrinter

消息发送、处理, 核心

=========================================
  * 创建 Message
        Message.obtain(...)
 
  * Message 包装的数据
        what
        arg1
        arg2
        obj
        
        setData(Bundle bundle)
 
  * 发送消息
        1. handler.sendMessage(msg)
        2. handler.sendEmptyMessage(what)  
        3. Message.obtain(handler, ...).sendToTarget()
        4. handler.post(new Runnable() {...})
        5. handler.obtainMessage(...).sendToTarget()

  * 处理消息
        1. 在 Message 上外接 Runnable
        2. 在 Handler 上外接 Callback
        3. 重写 Handler 的 handleMessage()

工作线程中通过 Looper 接收、处理消息

============================================
  工作线程中执行:
      
      Looper.prepare();
          创建消息队列,
          并创建 Looper 实例,
          然后将 Looper 实例绑定到当前线程
      
      handler = new Handler();
          从当前线程或得 Looper,
          Handler 会持有此 Looper 对象
      
      Looper.loop();
          进入死循环,
          等待其他线程向当前工作线程发送消息

HandlerThread

====================================
  * Thread 子类
  * 提供一个包含 Looper/MessageQueue的线程
  * 方法
  -----------------------
    getLooper() 
        获得该线程内的 Looper
        handler = new Handler(t.getLooper());

AsyncTask

======================================
  * 异步任务
  * 包装了 Handler 、 Message、 消息处理,线程
  * 如果创建启动多个异步任务,默认只有一个线程依次执行这些任务
  * 如果希望多个异步任务并行被处理,
    executeOnExecutor(Executor)
    executeOnExecutor(Executor, ...)
    *) 内建线程池:
       AsyncTask.SERIAL_EXECUTOR
       AsyncTask.THREAD_POOL_EXECUTOR
    *) 自定义线程池:       
       用 Executors 创建
   
  泛型
  ------------------------------------
    AsyncTask<A,B,C>
    
        A 执行此任务的参数数据类型
        B 表示执行进度的数据类型
        C 运行结果数据类型

  方法
  ------------------------------------
       doInBackground(...)    工作线程中执行
       publishProgress(...)   在 doInBackground() 中调用,发布进度信息
       onProgressUpdate(...)  在主线程执行,更新进度UI
       onPostExecute(...)     在主线程执行,处理最终结果
       
       cancel(true)           在主线程中用来取消异步任务,在 doInBackground() 完成之后,不向主线程发送消息,也就是说,onPostExecute() 不会执行           
                              如果参数给 true,会打断工作线程(如果工作线程有暂停)

       execute(...)
          新起线程,参数会被传递到 doInBackground() 方法
       
       executeOnExecutor(Executor pool, ...)
          在线程池内执行

你可能感兴趣的:(线程,AsyncTask)