最近作9.0項目,發現開機的時候,會先顯示壁紙一段時間,再去加載launcher,若是壁紙是黑色的,則會致使開機動畫結束後,顯示黑屏一段時間,再看到launcher。java
遇到問題,固然就是看開機日誌了。一番折騰,找到比較有用的log以下:android
20:10:50.453 769 1910 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.example.user.myapplication/.FallbackHome} from uid 0 on display 0
20:10:54.376 2029 2029 D FallbackHome: User unlocked and real home found; let's go!
20:10:54.466 769 2207 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.HOME] flg=0x10000100 cmp=com.google.android.setupwizard/.SetupWizardActivity} from uid 0 on display 0
複製代碼
原來在啓動launcher前,系統先啓動了一個FallbackHome的界面,接着再啓動launcher,這中間差了4秒,這跟現象對上了,即先顯示一段時間的壁紙,再啓動launcher。微信
那FallbackHome是什麼呢? FallbackHome是原生setting的一個activity,且配置了DirectBoot mode。launcher啓動的時候會先啓動到這個界面,用戶解鎖後,纔會調用finish,結束該界面,從而進入到真正的launcher界面。app
若未解鎖就等待ACTION_USER_UNLOCKED廣播後再去啓動Launcher。非DirectBoot模式下的launcher耗時4s就是在等待finishBooting後的系統廣播ACTION_USER_UNLOCKED。async
FallbackHome就是應DirectBoot功能而新增的一個頁面,具體DirectBoot功能不在這裏贅述,你們可自行了解。動畫
那如何解決掉處於DirectBoot模式下的黑屏呢?ui
嘗試了多種方案,最終比較完美的方案以下:google
經過延長開機動畫,等進入到非DirectBoot模式,再結束開機動畫。spa
但屏蔽掉關閉開機動畫以及開機動畫服務結束檢測相關代碼:調試
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
private void performEnableScreen()方法:
.....
/* 這裏屏蔽掉一些代碼
if (!mBootAnimationStopped) {
Trace.asyncTraceBegin(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0);
// stop boot animation
// formerly we would just kill the process, but we now ask it to exit so it
// can choose where to stop the animation.
SystemProperties.set("service.bootanim.exit", "1");
mBootAnimationStopped = true;
}
if (!mForceDisplayEnabled && !checkBootAnimationCompleteLocked()) {
if (DEBUG_BOOT) Slog.i(TAG_WM, "performEnableScreen: Waiting for anim complete");
return;
}
try {
IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger");
if (surfaceFlinger != null) {
Slog.i(TAG_WM, "******* TELLING SURFACE FLINGER WE ARE BOOTED!");
Parcel data = Parcel.obtain();
data.writeInterfaceToken("android.ui.ISurfaceComposer");
surfaceFlinger.transact(IBinder.FIRST_CALL_TRANSACTION, // BOOT_FINISHED
data, null, 0);
data.recycle();
}
} catch (RemoteException ex) {
Slog.e(TAG_WM, "Boot completed: SurfaceFlinger is dead!");
}
*/
....
}
複製代碼
這裏屏蔽了系統結束開機動畫的代碼,那麼得找一個地方去結束開機動畫,從而啓動launcher。
FallbackHome具有home屬性,launcher也必帶home屬性。那麼咱們能夠經過判斷系統所啓動的應用爲Home應用但又不是FallbackHome時,就能夠結束開機動畫了。
在以下地方去結束開機動畫:
frameworks/base/services/core/java/com/android/server/am/ActivityRecord.java
private void reportLaunchTimeLocked(final long curTime) {
....
//mnq, 20190819, @ {
//Log.d(TAG, "reportLaunchTimeLocked......" + shortComponentName + " intent" + intent);
if (isHomeIntent(intent) && shortComponentName != null && !shortComponentName.contains("FallbackHome")) {
SystemProperties.set("service.bootanim.exit", "1");
Log.d(TAG, "reportLaunchTimeLocked:real home....." + shortComponentName);
}
//mnq, 20190819, @}
}
複製代碼
如此更改後,開機後,發現系統不會有黑屏的現象,且開機動畫結束後就進入到了launcher界面了。
MTK平臺上,也會有此問題,不夠它會在界面上有一個友好的提示:
Phone is starting....
複製代碼
告知用戶,此時機器正在啓動中。
這個其實同樣,也能夠用這個辦法去處理。
若是文章存在錯誤描述,可直接留言,一塊兒探討!
我在微信公衆號也有寫文章,更新比較及時,有興趣者能夠關注以下公衆號!