承接上一篇文章驳糯,當(dāng)我們進入startLoader方法中,看到最后有這樣一行代碼
sWorker.post(mLoaderTask);
第一想法是開啟了子線程介蛉,要執(zhí)行耗時操作,想想也對加載數(shù)據(jù)當(dāng)然是耗時操作要開啟子線程斥扛。但是別急者去看runnable中的邏輯,先來看看sWorker這個Handler吧丹锹。
private static final Handler sWorker = new Handler(sWorkerThread.getLooper());
平時我們創(chuàng)建Handler對象就直接new一個了犹赖,為什么這個構(gòu)造要傳入一個參數(shù)呢,獲取的是一個Looper卷仑,那這個Looper是哪個線程的Looper呢峻村?再來看看sWorkerThread對象。
private static final HandlerThread sWorkerThread = new HandlerThread("launcher-loader");
是一個HandlerThread的類锡凝,看HandlerThread的源碼是一個Thread的子類粘昨,好先到這里,下一篇在具體說說Launcher中我們可以學(xué)習(xí)的一些設(shè)計方式窜锯,現(xiàn)在我們只要知道Handler執(zhí)行了post方法张肾,因為你對應(yīng)Handler的Looper是在子線程中創(chuàng)建的,所以代碼要在子線程中執(zhí)行post方法參數(shù)中Runnable類中的run方法的邏輯锚扎。
進入的LoaderTask這個內(nèi)部類中吞瞪,直接找到run方法:這其中比較重要的兩行代碼如下
....
isUpgrade = loadAndBindWorkspace();
...
loadAndBindAllApps();
第一行代碼是用來加載和顯示手機Launcher桌面上的數(shù)據(jù),第二行代碼是用來加載Launcher中應(yīng)用菜單列表中的所有的APP數(shù)據(jù)驾孔。這里說的的是原生的安卓應(yīng)用(模擬器上的Android系統(tǒng)就是原生的)芍秆,想小米改過的系統(tǒng)就只有一級桌面了,沒有了中間的應(yīng)用菜單列表按鈕翠勉。先看第一個方法
private boolean loadAndBindWorkspace() {
...
isUpgradePath = loadWorkspace();
....
//第一個參數(shù)是負數(shù)妖啥,表示需要對所有的桌面頁進行刷新。如果正數(shù)或者0对碌,表示對指定頁面進行刷新荆虱。
//第二個參數(shù)表示是否需要清理桌面的重復(fù)數(shù)據(jù)。
bindWorkspace(-1, isUpgradePath);
....
}
這個方法中最重要的是這兩行代碼朽们,第一行怀读,看方法名就知道它是用來加載數(shù)據(jù)的,第二行是用來講數(shù)據(jù)綁定到控件上顯示出來的骑脱。
loadWorkSpace()當(dāng)中的邏輯比較多了菜枷,在這里就不貼代碼了,它主要是從數(shù)據(jù)庫中獲取到對應(yīng)的字段惜姐,通過集合傳遞到bindWorkspace方法中犁跪,然后bindWorkspace方法通過回調(diào)接口椿息,將數(shù)據(jù)傳遞到Launcher中完成數(shù)據(jù)和控件的綁定來實現(xiàn)數(shù)據(jù)的展示歹袁。
private void loadAndBindAllApps() {
....
loadAllApps();
....
onlyBindAllApps();
}
同理對于加載應(yīng)用菜單列表中的應(yīng)用來說坷衍,也是先加載然后綁定這樣的邏輯,但是和加載桌面數(shù)據(jù)不同的是在loadAllApps()方法中沒有通過數(shù)據(jù)庫來加載条舔,使用的是PackageManager來獲取手機中的所有應(yīng)用(這里需要說明一下枫耳,我的講解中使用的是Android4.4的Launcher源碼來說,在Android5.0中加入了多賬戶的機制之后孟抗,這里就不是使用的PackageManager來實現(xiàn)獲取所有應(yīng)用了迁杨,5.0之后就是獲取的登錄賬戶的所有應(yīng)用)。然后onlyBindAllApps()方法就和上面一樣了凄硼,拿到數(shù)據(jù)調(diào)用回調(diào)接口铅协,將數(shù)據(jù)傳遞到Launcher中,展示數(shù)據(jù)摊沉。
這就是基本的Launcher的加載邏輯狐史,這里值得要提一下的是,如果想要屏蔽掉應(yīng)用菜單列表说墨,把所有的應(yīng)用都加載到桌面上骏全,Google在系統(tǒng)中提供了一個開關(guān),在Hotseat.java這個類中的resetLayout()中有一個if判斷尼斧,當(dāng)這個if判斷是true的時候就是顯示應(yīng)用菜單按鈕姜贡,false就是顯示應(yīng)用菜單按鈕。
下一篇我們就一起來看看在Launcher中有哪些很好的邏輯實現(xiàn)可以學(xué)習(xí)的棺棵。
歡迎關(guān)注我的微信公眾號楼咳,我會把一些生活的感想和投資方面的總結(jié)寫到公眾號,希望你能來和我一起交流技術(shù)之外的東西烛恤。