當我們打開FBReader程序的一刻,代碼會立即創建一個子線程。之后,主線程會負責在屏幕上顯示一個進度條,而子線程則在后台開始讀取epub文件。
PS:進度條的樣子如下圖所示,不過由於加載速度很快,這進度條都是一閃而過的。這張圖片是在單步調試的環境下截取的。
在這一章,我們將詳細介紹,程序如何創建子線程,以及如何控制進度條的顯示與消失。
本章涉及的核心類是UIUtil類。
FBReader默認首先進入的FBReader類,這是在AndroidManifes.xml設定的。
ZLAndroidActivity類中的onCreate方法
FBReader類的onCreate方法會首先觸發FBReader類的父類ZLAndroidActivity類中的onCreate方法。
這個方法中進行了一系列的初始化工作:
102行:設置程序為全屏
107行:設置程序的界面,這個界面是ViewZLAndroidWidget類。我們會在第十章“epub文件處理 -- 顯示”中詳細分析這個類的onDraw方法。
110行:調用ZLAndroidLibrary類的setActivity方法,為ZLAndroidLibrary類里面的myActivity變量賦了值(請大家記住這個方法,我們馬上會用到這個變量)
114行:調用FBReader類的createApplication方法,返回一個FBReaderApp類
117行:調用FBReaderApp類的子類FBReaderApp中的initWindow方法,這個方法方法將負責建立子線程,並在主線程顯示進度條
FBReaderApp類的initWindow方法、ZLAndroidApplicationWindow類wait方法
FBReaderApp類的initWindow方法調用了ZLApplication類的wait方法。而ZLApplication類的wait方法又會最終調用ZLAndroidApplicationWindow類wait方法
請記住initWindow方法中定義的Runnable類,這個類中的內容就是之后要在子線程中要運行的讀取epub文件的代碼。
還記得剛才要大家記住的ZLAndroidLibrary類的setActivity方法嗎?當時這個方法,給ZLAndroidLibrary類的myActivity變量賦了值。現在ZLAndroidLibrary類的wait方法會判斷這個屬性,如這個屬性為null,就會直接在主線程中運行讀取epub文件的代碼(這樣可能會造成主線程中的UI產生停滯);如果這個屬性不為null,就會調用UIUtil類的wai方法,分兩個線程處理程序
UIUtil類wait方法
在UIUtil類中的wait方法中,我們可以看到代碼新開了一個子線程(78行),子線程中運行的代碼是ZLApplication類的FBReaderApp類的initWindow方法中定義的Runnable類中的內容。同時,主線程調用ProgressBar類的show方法顯示了一個進度條(我們會在下一章中詳細介紹如何獲得進度條中要顯示的字)。
關於進度條,有兩個部分需要詳細介紹一下:第一是如何讓進度條消失,第二是如何獲取進度條要顯示的文字。
進度條的消失
首先來介紹如何讓ProgressBar消失。
讓進度條顯示的方法很簡單,只要調用ProgressDialog類的show方法即可。
ourProgressHandler變量指向的Handler類中一旦收到子線程的“通知”就會讓進度條消失
這里要請大家注意一下,UIUtil類的wait方法考慮到了多重后台任務的情況下,進度條怎樣顯示與消失。多重后台任務的情況,肯定必須是所有任務都完成的情況下,才能讓進度條消失,那么代碼是如何實現的呢?
代碼首先在UIUtil類的wait方法中用ourTaskQueue屬性保存所有的后台任務
然后,在Handler類中判斷ourTaskQueue中是否為空,為空時才讓進度條消失
同時,因為子線程和Handler類都在操作ourTaskQueue,必須使用wait方法和notify方法保證整個變量線程安全
進度條上要顯示的文字
接下來,介紹如何獲取ProgressBar要顯示的文字
顯示在進度條上的文字就是從資源文件里面讀取出來的message變量。
資源文件的位置在assets/resourses中application和zlibrary兩個文件夾中。
這兩個文件夾中存儲了各種語言的版本,其中FBReader程序默認的是uk.xml,而代碼最終會根據手機的語言設置,去顯示zh.xml中的內容。
我們要尋找的顯示在ProgressBar中的文字就在application文件夾中zh.xml文件中dialog節點下的waitMesssage節點下的loadingBook節點的value屬性。
代碼具體如何解析zh.xml文件,來獲取指定節點下的value屬性,我們將在下一章中介紹。
轉自:http://my.oschina.net/u/938986/blog/335567