========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41900879
========================================================

Android 的使用中经常会遇到从子线程切换到主线程进行界面更改的情况的;如果在一个Activity 中进行倒好说一个 Handler 即可解决问题;但是假如很多个界面呢?每个界面都建立一个Handler 么?太浪费了吧?咱们要的是简洁;要的是效率!走起。。。。

本来打算在原来的文章 [Android] 任意时刻从子线程切换到主线程的实现 上面进行修改的;但是发现没法啊;原来的那个出了些问题导致很难编辑,一编辑就乱的不成样了;无奈新开了一章。我想应该与其中我复制了大量的有样式的代码有关。

在上一章 [Android] 任意时刻从子线程切换到主线程的实现 中介绍了其具体的实现方式;但是没有系统的说一下原理;在这里就叙说一下。

原理

Handler原理:

[Android] 任意时刻从子线程切换到主线程的实现原理及加强版_第1张图片

当然其有很多细节部分没有一一画出来,这里就先过去了;将就看看啊 哈哈。

ToolKit 一键操作原理:

[Android] 任意时刻从子线程切换到主线程的实现原理及加强版_第2张图片

这里直接看或许会有些麻烦;一定要先看看上一章 [Android] 任意时刻从子线程切换到主线程的实现 中的内容后再看。不然这个图片就是一个废图。

New

都说了要加入新的功能,是啥呢?在上一章中说了有一种同步方法;该方法将会等待主线程执行了子线程的任务后,子线程才返回。这种是属于比较赖皮的形式。

假如子线程是女神,主线程是你;现在女神等你做事儿;但是呢你的人缘比较不错有很多女神都把任务给你;而其中一个女神就不乐意了;她就想要是你慢慢的做,我还这么等着你,岂不是太给你面子了。

然后女神就想,我等你半个小时吧;如果半个小时了你做了那我就接受你吧,如果没有那就拜拜吧。

针对这样的时间等待情况我们就需要加入一个新的方法:    public static void runOnMainThreadSync(Runnable runnable, int waitTime, boolean cancel)

原来的 public static void runOnMainThreadSync(Runnable runnable)

    public static void runOnMainThreadSync(Runnable runnable) {        if (Looper.myLooper() == Looper.getMainLooper()) {            runnable.run();            return;        }        SyncPost poster = new SyncPost(runnable);        getMainPoster().sync(poster);        poster.waitRun();    }
现在我们建立一个新的方法,只需要在上面改动几下。

新的 public static void runOnMainThreadSync(Runnable runnable, int waitTime, boolean cancel):

    public static void runOnMainThreadSync(Runnable runnable, int waitTime, boolean cancel) {        if (Looper.myLooper() == Looper.getMainLooper()) {            runnable.run();            return;        }        SyncPost poster = new SyncPost(runnable);        getMainPoster().sync(poster);        poster.waitRun(waitTime, cancel);    }
可以看见其中多了两个参数,一个是女神等待的时间:waitTime ;第二个参数就是女神走了后 你究竟还做不做该女神下达的任务(cancel)

女神:子线程
你:主线程

当然对应的 SyncPost 中的 public void waitRun() 方法也需要新添加一个类似的方法,为了解释就直接添加方法了,没有在原来的方法上修改。

原来的:public void waitRun():

    public void waitRun() {        if (!end) {            synchronized (this) {                if (!end) {                    try {                        this.wait();                    } catch (InterruptedException e) {                        e.printStackTrace();                    }                }            }        }    }
新添加的:public void waitRun(int time, boolean cancel):

    public void waitRun(int time, boolean cancel) {        if (!end) {            synchronized (this) {                if (!end) {                    try {                        this.wait(time);                    } catch (InterruptedException e) {                        e.printStackTrace();                    } finally {                        if (!end && cancel)                            end = true;                    }                }            }        }    }
可以看见其中的   this.wait(time); 进行了时间等待。

同时在完成后我们根据情况改变了 END 变量的状态。当然这里改变了,那么你做任务的时候就需要先判断了。

所以原来的执行方法:public void run():

    public void run() {        synchronized (this) {            runnable.run();            end = true;            try {                this.notifyAll();            } catch (Exception e) {                e.printStackTrace();            }        }    }
要更改为:

    public void run() {        if(!end) {            synchronized (this) {                if(!end) {                    runnable.run();                    end = true;                    try {                        this.notifyAll();                    } catch (Exception e) {                        e.printStackTrace();                    }                }            }        }    }
也就是在进入 同步前与同步后分别进行判断该状态是否为Flase如果是则证明需要执行;那么就进行执行。

代码部分就OK了,大家可以测试测试!

场景

针对上面新加的功能有如下场景:前提(女神叫你做事情;最长等待时间半个小时!)

  • 女神和你在一起,那么立刻就做事情。(此时女神就是主线程的情况,实际工作折就是女神;也可以说是你;因为你也是主线程)
  • 女神等了半个小时然后走了,至于之后你做不做女神给你的这个任务取决于女神的态度
  • 女神还没有等你就开始做了,此时女神压根儿就不会想等待的事情;也就是说不会执行到 this.wait(time);  语句;因为获取到同步块后就退出了。她等待的时间是花在等待进入同步块上。
  • 女神已经开始等待了12分钟了;此时你开始做了你在18分钟内完成了;那么说明是按时完成任务。
  • 女神已经开始等待了12分钟了;此时你开始做了,但是你还需要20分钟完成,女神在你完成前走了;此时不管女神说叫你做还是不做你都会把它做完的;你是个有责任的男人。

总结

  • cancel 变量只有在等待时间到了你却还未执行的情况下才有效果。
  • 任务一旦开始执行就不会中途退出,无论此时女神是否走了。

代码:

UIKit.java
UIKitHandlerPoster.java
UIKitSyncPost.java


========================================================
作者:qiujuer
博客:blog.csdn.net/qiujuer
网站:www.qiujuer.net
开源库:Genius-Android
转载请注明出处:http://blog.csdn.net/qiujuer/article/details/41900879
========================================================

更多相关文章

  1. Android中handler的作用与线程
  2. Android的线程和内存模型
  3. 【Android 并发编程】线程间通信的三种基本方式
  4. Android开发UI之在子线程中更新UI
  5. android 简单线程同步之CountDownLatch

随机推荐

  1. Android(安卓)不明确key时遍历JSONObject
  2. Error running app: Default Activity No
  3. android ubuntu no permissions
  4. android studio快捷键集合
  5. 在Eclipse中安装ADT
  6. 关于android WebViewClient 的方法解释
  7. 全局捕获异常,并输出到日志文件
  8. 2018-03-06
  9. Android(安卓)- JUnit Test(单元测试)
  10. Unity3d与Android的相互调用