[Android] 任意時刻從子線程切換到主線程的實現原理及加強版

來源:互聯網
上載者:User

標籤:android   非同步   子線程切換到主線程   genius   handler   

========================================================
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原理:


當然其有很多細節部分沒有一一畫出來,這裡就先過去了;將就看看啊 哈哈。

ToolKit 一鍵操作原理:


這裡直接看或許會有些麻煩;一定要先看看上一章 [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 變數只有在等待時間到了你卻還未執行的情況下才有效果。
  • 任務一旦開始執行就不會中途退出,無論此時女神是否走了。

代碼:

ToolKit.java
HandlerPoster.java
SyncPost.java


========================================================
qiujuer
部落格:blog.csdn.net/qiujuer
網站:www.qiujuer.net
開源庫:Genius-Android
轉載請註明出處:http://blog.csdn.net/qiujuer/article/details/41900879
========================================================

[Android] 任意時刻從子線程切換到主線程的實現原理及加強版

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.