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