android知识回顾---消息机制

Handler  Looper   MessageQueue  Message

1.Handler的机制流程

  如果在主线程中new Handler,Activity创建的时候会创建Looper,创建Looper的时候会创建MessageQueue,通过looper.mQueue()能得到MessageQueue对象,如果不是在主线程中new Handler就需要 通过Looper.prepare() 来初始化looper。当Handler.sendMessage(Message)到MessageQueue,该函数里面设置了那个Message对象的target属性是当前Handler对象,然后looper.prepare初始化looper,通过looper.mQueue获取MessageQueue对象,looper.loop 是一个轮询MessageQueue对象的方法,loop会获取MessageQueue对象的next方法来对消息队列进行轮询Message,MessageQueue是先进先出原则,

loop方法:

public static void loop() { 

     final Looper me = myLooper(); //myLooper返回当前线程的Looper对象

 

     final MessageQueue queue = me.mQueue; // 取出Looper中的消息队列

 

     ... 

     for (;;) { 

         Message msg = queue.next(); // might block 

         if (msg == null) { 

             ...         

            //quit

             return; 

         } 

         ... 

         // 调用该消息的Handler,交给它的dispatchMessage处理

 

         msg.target.dispatchMessage(msg); 

         ... 

         // 消息的回收,回收到消息池中。

 

         msg.recycle(); 

     }

(MessageQueue最主要的两个方法  enqueueMessage和 next 插入和读取两个操作,读取同时会删除Message,enqueueMessage方法源码了解到是一个单链表的插入操作,next是一个无限循环的方法如果没有消息,则会阻塞在这里,如果有消息则会返回,并且从链表删除)Message msg = queue.next();  这是looper中loop方法中的代码,获取的Message,如果获取到则调用hander的dispatchMessage处理。具体例子可以参照子线程中更新ui



2.Handler 和Looper的同步关系?引出ThreadHandler

package com.zhy.blogcodes.intentservice;

import android.os.Bundle;

import android.os.Handler;

import android.os.HandlerThread;

import android.os.Message;

import android.support.v7.app.AppCompatActivity;

import android.text.Html;

import android.widget.TextView;

import com.zhy.blogcodes.R;

public class HandlerThreadActivity extends AppCompatActivity{

private TextView mTvServiceInfo;

private HandlerThread mCheckMsgThread;

private Handler mCheckMsgHandler;

private boolean isUpdateInfo;

private static final int MSG_UPDATE_INFO = 0x110; //与UI线程管理的handler

private Handler mHandler = new Handler();

@Override protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_thread_handler);

//创建后台线程 initBackThread();

mTvServiceInfo = (TextView) findViewById(R.id.id_textview);

}

@Override protected void onResume() {

super.onResume(); //开始查询 isUpdateInfo = true;

mCheckMsgHandler.sendEmptyMessage(MSG_UPDATE_INFO);

}

@Override protected void onPause() {

super.onPause(); //停止查询

isUpdateInfo = false;

mCheckMsgHandler.removeMessages(MSG_UPDATE_INFO);

}

private void initBackThread() {

mCheckMsgThread = new HandlerThread("check-message-coming");

mCheckMsgThread.start();

mCheckMsgHandler = new Handler(mCheckMsgThread.getLooper())

{

@Override public void handleMessage(Message msg) {

checkForUpdate();

if (isUpdateInfo) {

mCheckMsgHandler.sendEmptyMessageDelayed(MSG_UPDATE_INFO, 1000);

} }

}; }


/** * 模拟从服务器解析数据 */

private void checkForUpdate() {

try {

//模拟耗时 Thread.sleep(1000);

mHandler.post(new Runnable() {

@Override public void run() {

String result = "实时更新中,当前大盘指数:<font color='red'>%d</font>";

result = String.format(result, (int) (Math.random() * 3000 + 1000));

mTvServiceInfo.setText(Html.fromHtml(result)); } }); }

catch (InterruptedException e) { e.printStackTrace(); } }

@Override protected void onDestroy() {

super.onDestroy(); //释放资源

mCheckMsgThread.quit(); }}



ThreadHandler与Thread之间的差别,唯一区别是ThreadHandler中有looper 的创建以及MessageQueue的消息队列,不断的轮询队列中的消息

使用ThreadHandler threadHandler=new ThreadHandler("test handler");

threadHandler.start();

new Handler(thread.getLooper()){

};

一个handler对应一个线程,这个线程不是主线程,所有可以再handlerMessage中做耗时操作,但是一般的Handler就不可以。



3.Handler 使用如何会导致内存泄漏及解决方案?






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值