Android的Looper使用-关于Android异步消息处理机制
最近在Android项目中看到这个关键词,一时间无从下手,这里先卖个关子:
new Thread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "弹个Toast", Toast.LENGTH_SHORT).show();
}
}).start();
直接在子线程弹个Toast的时候会出现崩溃,日志如下:
但是加上Looper又可以正常弹出Toast:
new Thread(new Runnable() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(MainActivity.this, "弹个Toast", Toast.LENGTH_SHORT).show();
Looper.loop();
}
}).start();
关于Looper的作用看这篇文章:Android异步消息处理机制完全解析,带你从源码的角度彻底理解 - 郭霖的专栏 - CSDN博客 –这篇也可作为Handler源码的简单分析
运用Semaphore 来保证合理的使用资源
public final class RunInMain {
/**
* 在主线程运行runnable
* @param waitUntilDone 直到等待完成
* @param job runnable接口
*/
public static void dispatch(final boolean waitUntilDone, final Runnable job) {
//主线程的标志
boolean alreadyInMain = Thread.currentThread() == Looper.getMainLooper().getThread();
if (alreadyInMain) {
//如果是在主线程的话,直接运行
job.run();
} else {
//如果不是在主线程的话,那么需要用到handler异步处理消息机制
//这个Semaphore被称为信息量,http://www.jianshu.com/p/0090341c6b80(我暂时还没有看懂)
final Semaphore semaphore = new Semaphore(0);
new Handler(Looper.getMainLooper()).post(new Runnable() {//在主线程创建handlder
@Override
public void run() {
job.run();//主线程运行
if (waitUntilDone) {
semaphore.release();//使得信息量容许的线程数加1
}
}
});
if (!waitUntilDone)
return;
try {
semaphore.acquire();//使得信息量容许的线程数减1
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void dispatch(Runnable job) {
dispatch(false, job);
}
}
当我看到这个Semaphore 的时候,我是一脸懵逼的,通过查看
Java的Semaphore使用总结 - CSDN博客 -这一篇建议运行一下他的代码理解以及
深入浅出java Semaphore - 简书 -这一篇建议看看源码
NO.54 并发限流: 信号量Semaphore
然后运用:
new Thread(new Runnable() {
@Override
public void run() {
RunInMain.dispatch(new Runnable() {
@Override
public void run() {
//这样它就回到主线程运行了
Toast.makeText(MainActivity.this, "弹个Toast", Toast.LENGTH_SHORT).show();
}
});
}
}).start();
这样子弹Toast也是没有任何问题的