文章分類:移動開發
學習記錄一下, 主要是Launcher啓動時從數據庫讀取各種桌面物件信息到最後顯示到屏幕桌面上的流程。
之前看2.0的時候,大概能分出來下面四個層次,2。1裏面基本一樣:
DB--mListInModel--mListInLauncher--ViewChildInCellLayout
I II III IV
掃了下代碼,Launcher裏面對這些東西有改動的重要是下面幾個函數
FunA: bindAppWidget(LauncherAppWidgetInfo item)
1. workspace add view. -->IV,add
workspace.requestLayout.
2. mDesktopItems add item. -->III,add
FunB: bindFolders(HashMap folders)
1. clear . mFolder. -->III,clear
2. mfolder. add -->III,add all
FunC: bindItems(ArrayList shortcuts,int start,itn end)
1. mDesktopItems. add . -->III,add
2. case APP|Short|Folder|LiveFoder|Search
add in workspace.screen -->IV,add
workspace.requestLayout.
FunD: completeAddApplication(Context context,Intent,CellLayout.CellInfo)
1. find place ,
2. workspace.dropExternal -->I, fix or add.
FunE: completeAddAppWidget(Intent,CellInfo)
1. create a AppWidgetProviderInfo .from appWidgetId. -->III, add
2. if didnt find slot : delete it -->III,del
else add to db. --->I, add
3. mDesktopItems add -->III,add
4. workspace add -->IV,add
FunF: completeAddLivefodler(Intent,CellInfo)
1.add to DB -->I
2.workspace add view -->IV
FunG: completeAddShortcut(Intent,CellInfo)
1.add to DB -->I
2.workspace add view -->IV
FunH: finishBindingItems()
1. every folder . add to workspace screen . -->IV,add
2. requestLayout.
3. requesetFocus for that opend
FunL: startBinding()
1. workspace.everyCellLayout.removeAllViewsInLayout -->IV.clear
涉及到content的流程:
1 onCreate ,開機 或者重啓
setupView初始化成員變量,然後由startLoader(isLaunching==true) 函數進行裝載。
startLoader這個函數,多數情況下這個boolean參數都是true,也就是說完全重新裝載。只有在changeFolderName,也就是改變用戶更改folder名字的時候,調用參數是false的狀況。
你一定覺得false的時候,系統會很聰明的去做最小的修改吧?嘿嘿,尼采錯了。
這個布爾參數只是用來調節後文會提到的那個Thread的權限的,用途是用戶開機的時候及早顯示免得用戶對着黑屏無聊- -b
兩種情況做的事情還是一樣的:完全的重讀重繪,從I->II->III->IV完全走一遍。
他做的事情對應上面層次結構裏的I->II->III->IV,
先把內容從ContentProvider讀出到自己的成遠變量, 然後傳遞給Launcher,最後傳給workspace的CellLayout的每個CellInfo的View,也就是畫到屏幕上。
具體來說,分以下幾步:
1)創建一個LoaderThread,然後mLoaderThread.start來啓動run函數
2)run函數第一步:loadWorkspace . 把數據庫中Launcher上的所有app,shortcut,search,folder,livefolder,appwidget.分類讀出來,前面2個放在一個arraylist<ItemInfo>,兩個folder放入 HashMap<Long, FolderInfo>, appwidget放入第二個arraylist這樣分成三類。這裏searchWidget是個怪東西,長着widget的個兒,跑app那裏去混。
3)run函數第二步:bindWorkspace
這個函數可以通過Callback這個神氣的東西找到launcher,然後向他的workspace發射剛纔讀出來的兩個數組。即包含了所有的數據庫中記錄的Launcher上的物件。
主要的,他通過callback調用三個launcher的函數:
Launcher.startBinding (即前面的FunL,把workspace的當前所有的view清空),
Launcher.bindItems(Func,綁定或者說裝載App,search,顯示到屏幕),
Launcher.bindFolders(FunB,邦好folder相關)
Launcher.bindAppWidget(FunA,綁定widget,顯示到屏幕)
最後,調用Launcher.finishBindingItems() ,上面提到的FunH, 把所有的folder裝載上,該顯示的folder用4*4個cell顯示起來。
細心的看官可能發現,三個bind函數,唯獨bindFolders是隻在III層操作,不和IV層相關,即不修改workspace的view的,原來是藏在finishBindingItems這個函數來作了。
4) run函數第三步 。 調用loadAllApps和bindAllApps
兩個函數一看就不是不山寨我們loadWorkspace和bindWorkspace的嘛。反正就是讀出來調用Launcher.bindAllApplications邦起來。
我這麼說是爲了方便理解,事實上app那塊兒mAllAppsList我。。覺得他寫的特棒,各種緩存各種區別各種花哨。直接看不懂。
到這裏launcher的onCreate就差不多了,機器界面上該顯示的也都顯示上了。
2 添加
Launcher 上面有兩種方式可以添加app快捷方式或者widget,分別是主界面空白處長按或者按下Menu選ADD。
其實點來點去,最後都是到了addItems()這個函數,他彈出一個窗口,讓你選想要添加的物件。
這些東西基本會調用一個startActivityForResult
而這些返回的Result回到Launcher的時候,會得到相應的處理
具體的處理在onActivityResult函數裏面。
3 刪除
刪除 沒啥好說的
分清楚I,II,III,IV有點用。 想在哪個層次上作修改,對照着來還蠻快。