關(guān)于Android9.0開(kāi)機(jī)黑屏一段時(shí)間才加載launcher界面的解決方法[轉(zhuǎn)載]

原文路徑:關(guān)于Android9.0開(kāi)機(jī)黑屏一段時(shí)間才加載launcher界面的解決方法

前言

最近做9.0項(xiàng)目,發(fā)現(xiàn)開(kāi)機(jī)的時(shí)候,會(huì)先顯示壁紙一段時(shí)間,再去加載launcher,如果壁紙是黑色的,則會(huì)導(dǎo)致開(kāi)機(jī)動(dòng)畫(huà)結(jié)束后,顯示黑屏一段時(shí)間,再看到launcher。

調(diào)試抓log

遇到問(wèn)題,當(dāng)然就是看開(kāi)機(jī)日志了。一番折騰,找到比較有用的log如下:

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

原來(lái)在啟動(dòng)launcher前,系統(tǒng)先啟動(dòng)了一個(gè)FallbackHome的界面,接著再啟動(dòng)launcher,這中間差了4秒,這跟現(xiàn)象對(duì)上了,即先顯示一段時(shí)間的壁紙,再啟動(dòng)launcher。

FallbackHome

那FallbackHome是什么呢?
FallbackHome是原生setting的一個(gè)activity,且配置了DirectBoot mode。launcher啟動(dòng)的時(shí)候會(huì)先啟動(dòng)到這個(gè)界面,用戶解鎖后,才會(huì)調(diào)用finish,結(jié)束該界面,從而進(jìn)入到真正的launcher界面。
若未解鎖就等待ACTION_USER_UNLOCKED廣播后再去啟動(dòng)Launcher。非DirectBoot模式下的launcher耗時(shí)4s就是在等待finishBooting后的系統(tǒng)廣播ACTION_USER_UNLOCKED。
FallbackHome就是應(yīng)DirectBoot功能而新增的一個(gè)頁(yè)面,具體DirectBoot功能不在這里贅述,大家可自行了解。

如何解決黑屏

那如何解決掉處于DirectBoot模式下的黑屏呢?
嘗試了多種方案,最終比較完美的方案如下:
通過(guò)延長(zhǎng)開(kāi)機(jī)動(dòng)畫(huà),等進(jìn)入到非DirectBoot模式,再結(jié)束開(kāi)機(jī)動(dòng)畫(huà)。
但屏蔽掉關(guān)閉開(kāi)機(jī)動(dòng)畫(huà)以及開(kāi)機(jī)動(dòng)畫(huà)服務(wù)結(jié)束檢測(cè)相關(guān)代碼:

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!");
        }
    */
    ....
}

這里屏蔽了系統(tǒng)結(jié)束開(kāi)機(jī)動(dòng)畫(huà)的代碼,那么得找一個(gè)地方去結(jié)束開(kāi)機(jī)動(dòng)畫(huà),從而啟動(dòng)launcher。
FallbackHome具備home屬性,launcher也必帶home屬性。那么我們可以通過(guò)判斷系統(tǒng)所啟動(dòng)的應(yīng)用為Home應(yīng)用但又不是FallbackHome時(shí),就可以結(jié)束開(kāi)機(jī)動(dòng)畫(huà)了。
在如下地方去結(jié)束開(kāi)機(jī)動(dòng)畫(huà):

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, @}
}

如此更改后,開(kāi)機(jī)后,發(fā)現(xiàn)系統(tǒng)不會(huì)有黑屏的現(xiàn)象,且開(kāi)機(jī)動(dòng)畫(huà)結(jié)束后就進(jìn)入到了launcher界面了。
MTK平臺(tái)上,也會(huì)有此問(wèn)題,不夠它會(huì)在界面上有一個(gè)友好的提示:

Phone is starting....

告知用戶,此時(shí)機(jī)器正在啟動(dòng)中。
這個(gè)其實(shí)一樣,也可以用這個(gè)辦法去處理。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容