关于Java的Semaphore以及Android的Looper使用

来源:互联网 发布:软件授权码破解 编辑:程序博客网 时间:2024/06/07 05:44

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 - 简书 -这一篇建议看看源码

然后运用:

        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也是没有任何问题的

原创粉丝点击