/**
* @author Evan 2014-11-19
*
* 消息的的星光大道
* 不要界面,直接用日志打出来吧
* 消息机制中各个概念的理解(官方的话,我就不说了,这里只写个人理解,个人把他们分别理解为行军打仗的两大阵营)
* 主线程(甲方阵营)UIThread{
* 成员介绍:
* Hander :甲方司令 实例化myHander
* Looper : 甲方信使 实例化Loooer.getMainLooper
* MessageQueue : 甲方信箱 消息队列
* Message : 甲方信件
*
* }
* 子线程(乙方阵营)SubThread{
* 成员介绍:
* Hander :甲方司令 实例化mySubHander
* Looper : 甲方信使 实例化Loooer.getLooper,Looper.prepare;
* MessageQueue : 甲方信箱 消息队列
* Message : 甲方信件
*
* }
*
* 技能介绍:(甲方,乙方都有)
* Hander :司令官 召唤信使: 1.召唤己方信使 myHander.getLooper;getMainLooper 2.召唤乙方信使 SubThread.getLooper
* 处理消息:handMessage
* 读取信件:obtainMessage
* 发送信件:sendMessage sendMessageToTarget post(runnerable)
* Looper :信使 收取指令: Looper.getLooper(Looper的归属就是那个司令官发的指令)
* 整理信箱: Looper.prepare Looper.Loop;
* MessageQueue: 信箱 存放Message
*
* Message 信件:
*
*
* */
public class MsgAvenueOfStars extends Activity {
/*
* 定义主线程消息处理句柄
*
* */
private static MsgAvenueOfStars instance;
private Handler mHandler;
private Looper looper;
public static MsgAvenueOfStars getInstance(){
return instance;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
instance = this;
/**
* 初始化主线程全局looper
* */
looper = getMainLooper();//或者Looper.myLooper();
/**
* 初始化主线程消息处理的执行者,即交给mhander处理
* */
mHandler = new MyHander(this,looper);
/**
* 主线程向自己发送消息
*
* */
/**
* 第一种方式
* */
Message msg1 = new Message();
msg1.what = GlobalFinalStatic.CASE_ONE;
msg1.obj = "我是从主线程发送的消息,我是case one";
mHandler.sendMessage(msg1);
/**
* 第二种方式
* */
Message msg2 = mHandler.obtainMessage();
msg2.what = GlobalFinalStatic.CASE_TWO;
msg2.obj = "我是从主线程发送的消息,我是case two";
mHandler.sendMessage(msg2);
/**
* 两种方法比较
* new Message: 不管message池中有没有,都新建一个新的message实例
* obtainMessage: 从官方源码上看,它是从后台调用obtain方法,从message池中返回已存在或则新建的message实例,从而能避免创建对象,减少内存的开销了。
*
* */
/**
* 主线程给子线程发送消息
* case three 主线程把子线程的信使叫来,把消息交给子线程信使,让子线程的信使把消息交给子线程指挥官
* 该方法几个要点
* 1.子线程的信使要有子线程来任命,默认情况下子线程是没有信使的
* 2.子线程要提供信使接口可以让主线程能够召唤该信使
* 3.要使用稍微复杂点的线程知识,即,线程锁 ,当子线程的信使任命工作还没有完成时,要锁住线程,以免主线程在召唤时出现空指针的情况
* */
SubThreadOne subThread = new SubThreadOne(this);
subThread.start();
MySubHander mySubHander = new MySubHander(this, subThread.getLooper());
Message subMessage1 = mySubHander.obtainMessage();
subMessage1.what = GlobalFinalStatic.CASE_THREE;
subMessage1.obj = "我是从主线程发出的消息,我命令子线程信使传递我的命令,我是case three";
mySubHander.sendMessage(subMessage1);
/**
* 主线程给子线程发送消息
* case four 主线程把子线程的指挥官叫来,直接命令指挥官执行命令
*
*
* */ SubThreadTwo subThreadTwo = new SubThreadTwo(this);
subThreadTwo.start();
Message msg4 = mHandler.obtainMessage();
msg4.what = GlobalFinalStatic.CASE_FOUR;
msg4.obj = "我是从主线程发出的消息,我命令我的信使向子线程传递我的命令,我是case four";
subThreadTwo.getHandler().sendMessage(msg4);
/**子线程给主线程发送消息*/
SubThreadThree subThreadThree = new SubThreadThree(this);
subThreadThree.start();
/**
* 那么这种hander和线程不在一起的写法,如何通知线程更新UI呢?,
* 直接在hander的处理类中 调用MsgAvenueOfStars.getInstance().updateUI();
* */
}
public void updateUI(){
}
/**
* 统一主线程处理消息类
* */
public class MyHander extends Handler {
private static final String TAG = MyHander.class.getSimpleName();
private Context context;
public MyHander(Looper looper){
super(looper);
}
/**
* 个人习惯每个类都定义多个构造函数,特别是这种带context句柄的,感觉特别好用,,喜欢写自己的东西的朋友应该深有体会
* */
public MyHander(Context context,Looper looper){
super(looper);
this.context = context;
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case GlobalFinalStatic.CASE_ONE:
/*
* LogUtils 自动以日志工具类
*
* */
//MsgAvenueOfStars.getInstance().updateUI(); 通知Activity刷新UI
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break;
case GlobalFinalStatic.CASE_TWO:
/*
* LogUtils 自动以日志工具类
*
* */
//MsgAvenueOfStars.getInstance().updateUI(); 通知Activity刷新UI
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break;
case GlobalFinalStatic.CASE_FIVE:
/*
* LogUtils 自动以日志工具类
*
* */
//MsgAvenueOfStars.getInstance().updateUI(); 通知Activity刷新UI
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break;
default:
break;
}
}
/**
* 统一子线程处理消息类
* */
public class MySubHander extends Handler {
private static final String TAG = MySubHander.class.getSimpleName();
private Context context;
public MySubHander(Looper looper){
super(looper);
}
/**
* 个人习惯每个类都定义多个构造函数,特别是这种带context句柄的,感觉特别好用,,喜欢写自己的东西的朋友应该深有体会
* */
public MySubHander(Context context,Looper looper){
super(looper);
this.context = context;
}
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what) {
case GlobalFinalStatic.CASE_FOUR:
/*
* LogUtils 自动以日志工具类
*
* */
//MsgAvenueOfStars.getInstance().updateUI(); 通知Activity刷新UI
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break;
case GlobalFinalStatic.CASE_THREE:
/*
* LogUtils 自动以日志工具类
*
* */
//MsgAvenueOfStars.getInstance().updateUI(); 通知Activity刷新UI
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break;
case GlobalFinalStatic.CASE_ONE:
/*
* LogUtils 自动以日志工具类
*
* */
//MsgAvenueOfStars.getInstance().updateUI(); 通知Activity刷新UI
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break;
case GlobalFinalStatic.CASE_TWO:
/*
* LogUtils 自动以日志工具类
*
* */
LogUtils.d(TAG, msg.obj.toString());//写到控制台
LogUtils.writeToSd(context, msg.obj.toString());//写到sd卡文件
break; default:
break;
}
}
public class SubThreadOne extends Thread {
private final Object mLock = new Object();
private Context context;
private MySubHander mSubHander;
private Looper subLooper;//子线程的信使
private Looper mainLooper;//主线程的信使
private String name = "subThread";
public SubThreadOne(){
}
public SubThreadOne(Context context){
this.context = context;
Thread t = new Thread(null, this, name);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
synchronized (mLock) {
while (subLooper == null) {
try {
mLock.wait();
} catch (InterruptedException ex) {
}
}
}
}
/**
* 该方法必须在线程启动后才能调用
* */
public Looper getLooper(){
return subLooper;
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare();//实例化本线程的Looper对象,有个这句话,就表明该线程有了自己的信使
synchronized (mLock) {
subLooper = Looper.myLooper();//实例化信使,即任命subLooper为子线程的信使
mLock.notifyAll();
} Looper.loop();
}
public void quit() {
subLooper.quit();
}
public class SubThreadTwo extends Thread {
private final Object mLock = new Object();
private Context context;
private MySubHander mSubHander;
private Looper subLooper;//子线程的信使
private String name = "subThread";
public SubThreadTwo(){
}
public SubThreadTwo(Context context){
this.context = context;
Thread t = new Thread(null, this, name);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
synchronized (mLock) {
while (mSubHander == null) {
try {
mLock.wait();
} catch (InterruptedException ex) {
}
}
}
}
public SubThreadTwo(Context context,Looper looper){
this.context = context;
}
/**
* 该方法必须在线程启动后才能调用
* */
public Looper getLooper(){
return subLooper;
}
public MySubHander getHandler() {
synchronized (mLock) {
while (mSubHander == null) {
try {
mLock.wait();
} catch (InterruptedException ex) {
}
}
return mSubHander;
}
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
Looper.prepare();//实例化本线程的Looper对象,有个这句话,就表明该线程有了自己的信使
synchronized (mLock) {
subLooper = Looper.myLooper();
mSubHander = new MySubHander(context, Looper.myLooper());
mLock.notifyAll();
} Looper.loop();
}
public void exit() {
getHandler().post(new Runnable(){
public void run() {
Looper.myLooper().quit();
}
});
}
public class SubThreadThree extends Thread {
private final Object mLock = new Object();
private Context context;
private MySubHander mSubHander;
private MyHander mSuperHander;
private Looper subLooper;//子线程的信使
private Looper mainLooper;
private String name = "subThread";
public SubThreadThree(){
}
public SubThreadThree(Context context){
this.context = context;
Thread t = new Thread(null, this, name);
t.setPriority(Thread.MIN_PRIORITY);
t.start();
synchronized (mLock) {
while (mainLooper == null) {
try {
mLock.wait();
} catch (InterruptedException ex) {
}
}
}
}
public SubThreadThree(Context context,Looper looper){
this.context = context;
}
/**
* 该方法必须在线程启动后才能调用
* */
public Looper getLooper(){
return subLooper;
}
public MySubHander getHandler() {
synchronized (mLock) {
while (mSubHander == null) {
try {
mLock.wait();
} catch (InterruptedException ex) {
}
}
return mSubHander;
}
}
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
//Looper.prepare();//实例化本线程的Looper对象,有个这句话,就表明该线程有了自己的信使
synchronized (mLock) {
mainLooper = Looper.getMainLooper();
//mSubHander = new MySubHander(context, mainLooper);
mSuperHander = new MyHander(context,mainLooper);
Message msg = mSuperHander.obtainMessage();
msg.what = GlobalFinalStatic.CASE_FIVE;
msg.obj = "我是从子线程发送的消息,我命令主线程的指挥官来执行我的命令,case five";
mSuperHander.sendMessage(msg);
mLock.notifyAll();
}
}
public void exit() {
getHandler().post(new Runnable(){
public void run() {
Looper.myLooper().quit();
}
});
}