Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher
1 原理说明
开机以后,设备会有一个“android正在启动”这样的弹框,这个界面是一个叫FallbackHome的Activity来展示的。FallbackHome机制是Android系统启动过程中的一种降级处理机制。当系统启动时,如果默认的Launcher应用无法正常加载或出现错误,系统会自动启用FallbackHome来替代默认Launcher。但一般为了改善产品体验,最终决定移除弹窗页面,直接进入默认的Launcher,避免弹窗对用户界面的干扰。具体而言,FallbackHome机制包括以下内容:
- 默认Launcher故障检测:系统会检测默认的Launcher应用是否能够正常加载和运行。如果检测到故障,系统将启动FallbackHome。
- 解锁过程中的弹窗:在系统解锁之前,可能会出现一个"Android正在启动"的弹窗页面,用于指示系统正在加载和准备。这个弹窗页面通常出现在桌面壁纸上,用户需要等待系统完全解锁后才能进入默认的Launcher。
去掉FallbackHome的效果实际上是让FallbackHome的view不显示,然后开机启动动画延长一下,直到系统解锁后再停止开机动画,完成这样较为顺滑的过渡。
2 修改方案(Android Q R S)
具体修改方案如下(这里以S版本修改为主,Q和R有一些差异但原理不变):
@1 修改文件为:AOSP/packages/apps/Settings$ vim src/com/android/settings/FallbackHome.java,目的为FallbackHome不显示View,所以注释掉。修改内容为:
public class FallbackHome extends Activity { private static final String TAG = "FallbackHome"; private static final int PROGRESS_TIMEOUT = 2000; private boolean mProvisioned; private WallpaperManager mWallManager; private final Runnable mProgressTimeoutRunnable = () -> { //AGS add start //不显示任何内容,如果是黑色衔接,直接改这里就足够了,如果不是则需要 2,3步骤内容的修改 /* View v = getLayoutInflater().inflate( R.layout.fallback_home_finishing_boot, null); setContentView(v); v.setAlpha(0f); v.animate() .alpha(1f) .setDuration(500) .setInterpolator(AnimationUtils.loadInterpolator( this, android.R.interpolator.fast_out_slow_in)) .start();*/ //AGS add end getWindow().addFlags(LayoutParams.FLAG_KEEP_SCREEN_ON); }; //... }
@2 修改文件为:AOSP/frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java,目的为播放完开机动画后不退出开机动画,所以注释掉即可。修改内容为:
public class WindowManagerService extends IWindowManager.Stub implements Watchdog.Monitor, WindowManagerPolicy.WindowManagerFuncs { //... private void performEnableScreen() { synchronized (mGlobalLock) { ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: mDisplayEnabled=%b" + " mForceDisplayEnabled=%b" + " mShowingBootMessages=%b" + " mSystemBooted=%b mOnlyCore=%b. %s", mDisplayEnabled, mForceDisplayEnabled, mShowingBootMessages, mSystemBooted, mOnlyCore, new RuntimeException("here").fillInStackTrace()); if (mDisplayEnabled) { return; } if (!mSystemBooted && !mShowingBootMessages) { return; } if (!mShowingBootMessages && !mPolicy.canDismissBootAnimation()) { return; } // Don't enable the screen until all existing windows have been drawn. if (!mForceDisplayEnabled) { if (mBootWaitForWindowsStartTime = 0; i--) { if (mRoot.getChildAt(i).shouldWaitForSystemDecorWindowsOnBoot()) { return; } } long waitTime = SystemClock.elapsedRealtime() - mBootWaitForWindowsStartTime; mBootWaitForWindowsStartTime = -1; if (waitTime > 10) { ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waited %dms for all windows to be drawn", waitTime); } } //AGS add start //播放完开机动画后不退出开机动画,注释掉如下代码即可。 /* 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()) { ProtoLog.i(WM_DEBUG_BOOT, "performEnableScreen: Waiting for anim complete"); return; } try { IBinder surfaceFlinger = ServiceManager.getService("SurfaceFlinger"); if (surfaceFlinger != null) { ProtoLog.i(WM_ERROR, "******* 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) { ProtoLog.e(WM_ERROR, "Boot completed: SurfaceFlinger is dead!"); } */ //AGS add end EventLogTags.writeWmBootAnimationDone(SystemClock.uptimeMillis()); Trace.asyncTraceEnd(TRACE_TAG_WINDOW_MANAGER, "Stop bootanim", 0); mDisplayEnabled = true; ProtoLog.i(WM_DEBUG_SCREEN_ON, "******************** ENABLING SCREEN!"); // Enable input dispatch. mInputManagerCallback.setEventDispatchingLw(mEventDispatchingEnabled); } try { mActivityManager.bootAnimationComplete(); } catch (RemoteException e) { } mPolicy.enableScreenAfterBoot(); // Make sure the last requested orientation has been applied. updateRotationUnchecked(false, false); } //... }
@3 修改文件为:AOSP/frameworks/base/services/core/java/com/android/server/wm/ActivityRecord.java,目的为解锁后再结束开机动画。修改内容为:
public final class ActivityRecord extends WindowToken implements WindowManagerService.AppFreezeListener { /** Called when the windows associated app window container are drawn. */ //... private void onWindowsDrawn(long timestampNs) { if (mPerf != null && perfActivityBoostHandler > 0) { mPerf.perfLockReleaseHandler(perfActivityBoostHandler); perfActivityBoostHandler = -1; } else if (perfActivityBoostHandler > 0) { Slog.w(TAG, "activity boost didn't release as expected"); } final TransitionInfoSnapshot info = mTaskSupervisor .getActivityMetricsLogger().notifyWindowsDrawn(this, timestampNs); final boolean validInfo = info != null; final int windowsDrawnDelayMs = validInfo ? info.windowsDrawnDelayMs : INVALID_DELAY; final @WaitResult.LaunchState int launchState = validInfo ? info.getLaunchState() : WaitResult.LAUNCH_STATE_UNKNOWN; // The activity may have been requested to be invisible (another activity has been launched) // so there is no valid info. But if it is the current top activity (e.g. sleeping), the // invalid state is still reported to make sure the waiting result is notified. if (validInfo || this == getDisplayArea().topRunningActivity()) { mTaskSupervisor.reportActivityLaunched(false /* timeout */, this, windowsDrawnDelayMs, launchState); } finishLaunchTickingLocked(); if (task != null) { task.setHasBeenVisible(true); } //AGS add start if (isHomeIntent(intent) && shortComponentName != null && !shortComponentName.contains("FallbackHome")) { SystemProperties.set("service.bootanim.exit", "1"); //这里就是将上面注掉的代码copy过来 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, "Boot completed: SurfaceFlinger is dead!"); } } //AGS add end mLaunchRootTask = null; } //... }
(图片来源网络,侵删)(图片来源网络,侵删)
还没有评论,来说两句吧...