27:活用AndroidMessage Queue(2/3)

认识AndroidMessage Queue(2/3)

1. 复习Message Queue的角色

在上一篇里,介绍了AndroidThreadLooperMessage QueueHandler四者间之关系。

兹先复习如下:

l UI thread 通常就是main thread,而Android启动程序时(即诞生Process)会替它建立一个Message Queue

l 当然需要一个Looper之对象,来管理该Message Queue

l 我们可以诞生Handler之对象来push新讯息到Message Queue里;或者接收Looper(Message Queue取出)所送来的讯息。

l 线程AHandler对象参考可以传递给别的线程,让别的线程BC等能送讯息来给线程A(存于AMessage Queue)

l 线程AMessage Queue里的讯息,只有线程A所属的对象可以处理之。

了解了四者间之关系后,在本篇里,就能来思考如何让主线程与子线程之间互相沟通了。包括,子线程push讯息到主线程的Message Queue里,并触发主线程去执行某项工作(即执行某个函数)

2. 由别的线程送讯息到主线程的Message Queue()

在上一篇文章里,使用如下程序片段:

// class ac01 extends Activity {

// ………

public void onClick(View v) {

switch(v.getId()){

case 101:

t = new myThread();

t.start();

break;

case 102:

finish();

break;

}

}

//------------------------------------------------------

class EHandler extends Handler {

public EHandler(Looper looper) {

super(looper);

}

@Override

public void handleMessage(Message msg) {

tv.setText((String)msg.obj);

}

}

//------------------------------------------------------

class myThread extends Thread{

private EHandler mHandler;

public void run() {

Looper myLooper, mainLooper;

myLooper = Looper.myLooper();

mainLooper = Looper.getMainLooper();

String obj;

if(myLooper == null){

mHandler = new EHandler(mainLooper);

obj = "current thread has no looper!";

}

else {

mHandler = new EHandler(myLooper);

obj = "This is from current thread.";

}

mHandler.removeMessages(0);

Message m = mHandler.obtainMessage(1, 1, 1, obj);

mHandler.sendMessage(m);

}

}

}

这个mHandler定义于myThread类别里,而且由子线程执行指令:

mHandler = new EHandler(mainLooper);

来诞生EHandler之物件;但是这个mHandler确是属于main线程的(用来存取主线程的MessageQueue),所以指令:

mHandler.sendMessage(m);

是将m丢到主线程的MessageQueue里。

此外,我们也可以将mHandler定义于ac01类别里。如下程序范例:

//----- Looper_03范例 -----

package com.misoo.kx04;

import android.app.Activity;

import android.content.Context;

import android.graphics.Color;

import android.os.Bundle;

import android.os.Handler;

import android.os.Looper;

import android.os.Message;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.TextView;

public class ac01 extends Activity implements OnClickListener {

private final int WC = LinearLayout.LayoutParams.WRAP_CONTENT;

private final int FP = LinearLayout.LayoutParams.FILL_PARENT;

public TextView tv;

private myThread t;

private Button btn, btn2;

EventHandler h;

Context ctx;

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

ctx = this;

LinearLayout layout = new LinearLayout(this);

layout.setOrientation(LinearLayout.VERTICAL);

btn = new Button(this);

btn.setId(101);

btn.setBackgroundResource(R.drawable.heart);

btn.setText("test looper");

btn.setOnClickListener(this);

LinearLayout.LayoutParams param =

new LinearLayout.LayoutParams(100,50);

param.topMargin = 10;

layout.addView(btn, param);

btn2 = new Button(this);

btn2.setId(102);

btn2.setBackgroundResource(R.drawable.ok_blue);

btn2.setText("exit");

btn2.setOnClickListener(this);

layout.addView(btn2, param);

tv = new TextView(this);

tv.setTextColor(Color.WHITE);

tv.setText("");

LinearLayout.LayoutParams param2 =

new LinearLayout.LayoutParams(FP, WC);

param2.topMargin = 10;

layout.addView(tv, param2);

setContentView(layout);

}

public void onClick(View v) {

switch(v.getId()){

case 101:

h = new EventHandler(Looper.myLooper());

t = new myThread();

t.start();

break;

case 102:

finish();

break;

}

}

//------------------------------------------------

public class EventHandler extends Handler {

public EventHandler(Looper looper) {

super(looper);

}

@Override

public void handleMessage(Message msg) {

((Activity)ctx).setTitle((String)msg.obj);

}

}

//------------------------------------------------------

class myThread extends Thread{

public void run() {

String obj = "from myThread";

Message m = h.obtainMessage(1, 1, 1, obj);

h.sendMessage(m);

}

}

}

//------------------------------------------------------

指令:

h = new EventHandler(Looper.myLooper());

h是属于main线程的(用来存取主线程的MessageQueue)。在myThread类别里的指令:

h.sendMessage(m);

虽然是由子线程执行该指令,还是m丢到主线程的MessageQueue里。于是,子线程所执行的run()函数,就顺利将m丢给主线程(Message Queue),并触发了主线程去执行handleMessage()函数了。显示出画面如下:

1

上述的指令:

myLooper = Looper.myLooper();

mainLooper = Looper.getMainLooper();

………

mHandler = new EHandler(mainLooper);

………

mHandler = new EHandler(myLooper);

………

都明显地指明mHandler是负责存取哪一个线程的Message Queue。不过,有时候并不需要特别指明。例如上述的onClick()函数和EventHandler类别,可改写为:

//----- Looper_03aa 范例 -----

// class ac01 extends Activity {

// ………

public void onClick(View v) {

switch(v.getId()){

case 101:

h = new EventHandler();

t = new myThread();

t.start();

break;

case 102:

finish();

break;

}

}

//------------------------------------------------

public class EventHandler extends Handler {

@Override

public void handleMessage(Message msg) {

((Activity)ctx).setTitle((String)msg.obj);

更多相关文章

  1. android 进程与线程 - 开发文档翻译 - 线程
  2. Android软件安全与逆向分析
  3. android 进程与线程 - 开发文档翻译 - 进程
  4. android 进程与线程 - 开发文档翻译 - 线程
  5. Android(安卓)面试必备 - 线程
  6. 布局指令大全
  7. android 进程与线程 - 开发文档翻译 - 进程
  8. Android核心分析 之十一-------Android(安卓)GWES之消息系统
  9. android 进程与线程 - 开发文档翻译 - 线程

随机推荐

  1. 4.基础数据类型
  2. 虚拟机安装Linux复盘
  3. SpringBoot配置加载原理全面解析
  4. 学习第三周
  5. 干货 | 万字详解整个数据仓库设计体系
  6. 内部类
  7. Volatile原理概述
  8. HTML中表格和表单的应用实例
  9. RPC实战与核心原理
  10. 分布式数据库30讲