作者:FavoYang Email:favoyang@yahoo.com 歡迎交流
KeyWords:線程化模型 j2me UI設計
內容提要:
本文是《j2me進度條與線程化模型》一文的續(以后簡稱原文,沒看過的建議看一下)。
討論了原文中使用的線程模型的不足,并針對她的缺點提出了新的改進辦法并給出了改進后的實現。因原文中UI部分有靈活的擴展性,未作更改。
版權聲明:
本文同時發表在www.j2medev.com和我的Blog(blog.csdn.net/alikeboy)上,如果需要轉載,有三個途徑:1)聯系我并經我同意;2)和www.j2medev.com有轉載文章合作協議的 3)通過rss聚合我的Blog。另外轉載需要全文轉發(包括文章的頭部),不要斷章取義。
正文:
原文中模型,是一個前臺的PRogressGaugeUI與后臺線程無關的模型。這樣設計的時候最大程度上的化簡了通信的復雜性,實際上是一種單方向的模型(由BackgroundTask 向 PGUI通信)。按照這種模式的要求,程序員在Override BackgroundTask 的runTask()方法時,有義務定期的去查訓前臺的PGUI的運行情況,并根據這種情況做出反映。這樣這種模式完全相信后臺線程,將是否響應用戶cancel命令的權利交給了后臺線程,如果后臺線程陷入麻煩沒有響應了(比如訪問一個很昂貴的網絡連接),此時用戶試圖cancel也沒有用,程序將會暫時的死鎖,直到后臺線程有時間去檢查前臺的狀態。并且在實際情況中,到底什么時候去查詢,多大的頻率都是問題。在代碼段中過多的此類代碼,會影響對正常的流程的理解。
從下面的這個順序圖,可以看到這個具體流程:
我們需要一個方法,讓我們能夠強制的結束Task。這個方法由背景線程自己提供,取名叫做cancel()。當然沒有任何一個方法可以強迫線程立即結束(曾經有,因為安全性問題而被取消)。所以cancel()方法往往通過關閉的資源(一個連接,一個流等)來迫使runTask發生異常被中斷,runTask有義務根據自己的約定捕捉此類異常并立即退出。一圖勝千言,讓我們看看這種方法的流程。

很顯然的,關鍵在于前臺的線程對后臺的線程進行了回調,這樣就可以解決問題了。但是新的問題來了,這樣做迫使我們將前臺與后臺線程緊密的耦合在了一起(因為要回調嘛)。能不能既實現回調又避免前臺UI與后臺線程的緊密耦合呢?
幸好,我門可以利用接口來實現這一點。
先前的模型是這樣的:

為了降低耦合,我們建立一個接口
public interface Cancelable {
/**
* 本方法非阻塞,應該立即返回(如有必要開啟新的線程)
* 此外應避免對此方法的重復調用
*/
public void cancel();
}
接下來在ProgressObserver加入對這個方法的支持
public interface ProgressObserver {
……
……
/**
* 設置取消Task時回調的函數對象
* @param co
*/
public void setCancelalbeObject(Cancelable co);
}
這樣,就可以在用戶按下取消按鈕的時候,就可以進行對Cancelable.cancel()的回調。這樣靈活性大大增強了。
更新后的代碼如下,除了改用以上的模型外,還對部分的BUG進行了更正,更改的地方會用不同的顏色表示。詳細的用法可參見注釋
點擊瀏覽該文件
(出處:http://www.survivalescaperooms.com)
新聞熱點
疑難解答