android进程、Hander、Looper、Message、MessageQueue深入分析

进程的本质:cup分别执行两处不同的指令
进程的本质
微指令是程序的最小单位,所以线程的分割点也只能是在微指令的切换处。

线程、looper、Message、Handerl的关系
线程、looper、Message、Handerl的关系代码
看了《深入理解android内核数据思想》和《android开发的艺术》关于"线程、hander、message、MesageQueue、looper"的讲解,总感觉理解的还是不够深入,隔靴搔痒的感觉还是有,于是用java模拟一般关于上面的知识。感觉思路立马清晰。
在这里插入图片描述
线程基类

public class AndroidThread extends Thread {
	public AndroidThread mAndroidThread;
	public Looper mLooper = null;
	/**
	 * 获取当前线程
	 * @return
	 */
	public static AndroidThread currentThread(){
		Thread thread = Thread.currentThread();
		AndroidThread thread2 = (AndroidThread)thread;
		return thread2;
	}
	
	/**
	 * 向所在的线程发消息
	 * @param m
	 */
	public void sendEmptyMessage(Message m) {
		mLooper.mQueueList.add(m);
	}
}

线程B



public class AndroidThreadB extends AndroidThread {
	public Handler h;
	public Handler h2;
	AndroidThreadA mAndroidThreadA;
	
	/**
	 * 运转
	 */
	public void run() {
		Looper.prepare();
		h = new Handler();
		h.sendEmptyMessage(6);
		h2 = new Handler(){
			public void handlerMessage(Message m) {
				super.handlerMessage(m);
				if(m.whart==7) {
					Message message = h2.creatMessage(8);
					mAndroidThreadA.sendEmptyMessage(message);
				}
			
			}
		};
		h2.sendEmptyMessage(7);
		mian();
		Looper.loop();
		
	}
	
	/**
	 * 线程入口
	 */
	public void mian() {
		mAndroidThreadA = new AndroidThreadA();
		mAndroidThreadA.mAndroidThread = this;
		mAndroidThreadA.start();
	}
}

线程A



public class AndroidThreadA extends AndroidThread {
	public Handler h;
	
	/**
	 * 运转
	 */
	public void run() {
		Looper.prepare();
		h = new Handler();
		h.sendEmptyMessage(5);
		Looper.loop();
	}
}

Handler



import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.PriorityBlockingQueue;

public class Handler {
	public Looper mLooper;
	public LinkedList<Message> mQueueList;
	public Handler() {
		mLooper = Looper.myLooper();
		mQueueList = mLooper.mQueueList;
	}
	public void handlerMessage(Message m) {
		System.out.println("handlerMessage");
		System.out.println("m.whart"+m.whart);
		System.out.println(Thread.currentThread().getName());
		System.out.println("");
	}
	public void sendEmptyMessage(int what) {
		Message m = new Message(this);
		m.whart = what;
		mQueueList.add(m);
		mQueueList.add(new Message(this));
	}
	public Message creatMessage(int what) {
		Message m = new Message(this);
		m.whart = what;
		return m;
	}
}

Looper


import java.util.LinkedList;

public class Looper {
	public LinkedList<Message> mQueueList = new LinkedList<Message>();
	
	/**
	 * 构造函数
	 */
	public Looper() {
		AndroidThread thread = AndroidThread.currentThread();
		Looper looper =  this;
		thread.mLooper = looper;
	}
	
	/**
	 * 准备
	 */
	public static void prepare() {
		AndroidThread.currentThread().mLooper = new Looper();
	}
	
	/**
	 * 循环(静态)
	 */
	public static void loop() {
		AndroidThread thread2 = AndroidThread.currentThread();
		Looper loop = thread2.mLooper;
		loop.loop2();
	}
	
	/**
	 * 循环
	 */
	public void loop2() {
		while(true) {
			try {
				Message mes = mQueueList.getFirst();
				mes.callBack();
				mQueueList.remove(mes);
			}catch(Exception e){
				
			}
		}
	}
	
	/**
	 * 获取当前线程的looper
	 * @return
	 */
	public static Looper myLooper() {
		return AndroidThread.currentThread().mLooper;
		
	} 
}

Message



public class Message {
	public Handler mHandler;
	public int whart;
	public Message(Handler handler) {
		mHandler = handler;
	}
	public void callBack() {
		mHandler.handlerMessage(this);
	}
}

程序入口


public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("线程模拟");	
		
		AndroidThreadB aThread = new AndroidThreadB();
		aThread.start();
	}

}

运行结果

线程模拟
handlerMessage
handlerMessage
m.whart6
m.whart5
Thread-0

handlerMessage
m.whart0
Thread-0

handlerMessage
m.whart7
Thread-0

handlerMessage
m.whart0
Thread-0

Thread-1

handlerMessage
m.whart0
Thread-1

handlerMessage
m.whart8
Thread-1

代码2
1.基于本人的习惯,喜欢迅速的运行起来,然后再分析代码,这里将类写到一个文件里,方面拷贝代码。
2.android关于线程的Looper用了一个ThreadLocal类来处理各线程的Looper(尽管我没弄清楚这样的意图,但还是尽量模仿一下,在我看来这样是效率低下的,但不知道android这样设计的意图在哪里)

package androidThread3;
import java.util.HashMap;
import java.util.LinkedList;

class Athread extends Thread{
	public Handler mH;
	public Athread mFAthread;
	public void sendEmptyMessage(Message m) {
		Looper looper = Looper.myLooper();
		looper.mQueue.add(m);
	}
}
class ThreadA extends Athread{
	public void createHandler() {
		mH = new Handler() {
			public void handlerMessage(Message m) {
				super.handlerMessage(m);
				if(m.whart==1) {
					main();
				}
			}
		};
	}
	public void run() {
		Looper.prepare();
		createHandler();
		mH.sendEmptyMessage(1);
		Looper.loop();
	}
	public void main() {
		ThreadB tb = new ThreadB();
		tb.mFAthread = this;
		tb.start();
	}
}
class ThreadB extends Athread{
	
	public void createHandler() {
		mH = new Handler() {
			public void handlerMessage(Message m) {
				super.handlerMessage(m);
				if(m.whart==2) {
					Message msg = mH.creatMessage(3);
					mFAthread.sendEmptyMessage(msg);
				}
			}
		};
	}
	public void run() {
		Looper.prepare();
		createHandler();
		mH.sendEmptyMessage(2);
		Looper.loop();
	}
}
class Looper{
	public static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
	public MessageQueue mQueue = new MessageQueue();
	public static Looper myLooper() {
		Looper looper = sThreadLocal.get();
		return looper;
	}
	public static void prepare() {
		Looper looper = new Looper();
		sThreadLocal.set(looper);
	}
	public static void loop() {
		myLooper().loop2();
	}
	public void loop2(){
		for(;;) {
			Message msg = mQueue.next();
			if(msg!=null) {
				msg.callBack();
			}
		}
	}
	
}

class Handler{
	public Looper mLooper;
	public MessageQueue mQueue;
	public Handler() {
		mLooper = Looper.myLooper();
		mQueue = mLooper.mQueue;
	}
	public void handlerMessage(Message m) {
		System.out.println("handlerMessage");
		System.out.println("m.whart"+m.whart);
		System.out.println(Thread.currentThread().getName());
		System.out.println("");
	}
	public void sendEmptyMessage(int what) {
		Message m = new Message(this);
		m.whart = what;
		mQueue.add(m);
	}
	public Message creatMessage(int what) {
		Message m = new Message(this);
		m.whart = what;
		return m;
	}
}
class Message{
	public Handler mHandler;
	public int whart;
	public Message(Handler handler) {
		mHandler = handler;
	}
	public void callBack() {
		mHandler.handlerMessage(this);
	}
}
class MessageQueue{
	public LinkedList<Message> mQueueList = new LinkedList<Message>();
	public void add(Message message) {
		mQueueList.add(message);
	}
	public Message next() {
		Message mes=null;
		try {
			mes = mQueueList.getFirst();
			mQueueList.remove(mes);
		}catch(Exception e){
			
		}
		return mes;
	}
}
class ThreadLocal<T>{
	public HashMap<String,T> mLoopers;
	public ThreadLocal() {
		mLoopers = new HashMap<String,T>();
	}
	public void set(T t) {
		String threadName = Thread.currentThread().getName();
		mLoopers.put(threadName,t);
	}
	public T get() {
		String threadName = Thread.currentThread().getName();
		T t = mLoopers.get(threadName);
		return t;
	}
}
public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("android 线程模拟");
		
		ThreadA ta = new ThreadA();
		ta.start();
	}

}

运行结果

handlerMessage
m.whart1
Thread-0

handlerMessage
m.whart2
Thread-1

handlerMessage
m.whart3
Thread-1

学习总结
1.怎么跨进程
a.由硬件的角度看,应该是将函数的调用指令放到了不同的内存空间。
b.从现象删上看,哪里创建的回调对象(handle),在哪个线程上执行,具体原理,不清楚,可能需要分析虚拟机的原理。

2.Handelr和Message的关系:Handelr即是发消息者,也是处理消息者,这让人感觉有点困惑。为什么不直接调用呢,直接调用可以吗?还是通过如下几种情况说明吧:

handler是否跨进程的几种价值体现表
hander的价值
改变响应周期:将发消息和响应消息的时间拉开
跨对象调用:跨对象的消息通讯
跨线程:跨线程的消息通讯

消息的处理对象关系表
消除处理对象关系表
1.发送和处理的都是handler。
2.线程内Looper和MessageQueue都只有一个对象。
3.同线程内handler可以有多个,但发送到本线程的消息都发到一个消息队列中(MessageQueue)
4.Handelr可以把消息发送到其他线程的MessageQueue队列上

猜你喜欢

转载自blog.csdn.net/xie__jin__cheng/article/details/91863635
今日推荐