Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher

这篇具有很好参考价值的文章主要介绍了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) {
                    // First time we will start waiting for all windows to be drawn.
                    mBootWaitForWindowsStartTime = SystemClock.elapsedRealtime();
                }
                for (int i = mRoot.getChildCount() - 1; i >= 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,目的为解锁后再结束开机动画。修改内容为:文章来源地址https://www.toymoban.com/news/detail-819579.html

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;
    }
    //...
}

到了这里,关于Android Framework 常见解决方案(24)屏蔽FallbackHome,去除 Android正在启动,直接进入Launcher的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • VS2022迁移VS2019项目遇到的.Net Framework 引用程序集问题解决方案

    VS2022迁移VS2019项目遇到的.Net Framework 引用程序集问题解决方案

    在GitHub上发现TrafficMonitor的开源代码,想要自己过一遍这个项目 在VS2022上面打开出现了MSB3644错误,打开微软 “找不到项目所请求 .NET 版本的 .NET 引用程序集时,会发生此错误。 发生此问题的原因可能是项目文件存在问题,它所请求的版本无法识别或未安装;也可能是安装问

    2024年02月06日
    浏览(44)
  • 【解决方案】找不到依赖 “@tarojs/plugin-framework-react“,请先在项目中安装

    导入微信小程序项目,执行yarn build:weapp 或者npm run build:weapp后报错如下: 👽 Taro v3.5.12 找不到依赖 \\\"@tarojs/plugin-framework-react\\\",请先在项目中安装 报错原因是Taro的版本号和其他插件版本号不匹配。 解决方法是终端执行以下代码,添加或更新插件。

    2024年02月12日
    浏览(20)
  • 电脑服务器离线安装.net framework 3.5解决方案(错误:0x8024402c )(如何确定当前系统是否安装NET Framework 3.5)

    电脑服务器离线安装.net framework 3.5解决方案(错误:0x8024402c )(如何确定当前系统是否安装NET Framework 3.5)

            日常服务的搭建或多或少都会有需要到NET Framework 3.5的微软程序运行框架,本次介绍几种不同的安装方式主要解决运行在Windows 2012 以上的操作系统的服务。         .NET Framework是微软公司推出的程序运行框架,主要包含运行库和公共语言集,3.5是版本号, 目前最

    2024年02月19日
    浏览(10)
  • Unity常见的优化解决方案

    Unity常见的优化解决方案

    启用ForceToMono 如果此音频文件左右声道一样,没有立体声音即启用ForceToMono选项,如果左右声道有区别的话会导致声音出现问题 可以减少内存和磁盘占用 LoadType加载音频资源的选项 Decompress On Load • 压缩过的音频文件如果小于200KB以下的音频文件使用 Compressed In Memory • 如果大

    2024年04月14日
    浏览(19)
  • 正则常见问题及解决方案

    正则常见问题及解决方案

    使用正则处理问题的基本思路。有一些方法比较固定,比如将问题分解成多个小问题,每个小问题见招拆招:某个位置上可能有多个字符的话,就⽤字符组。某个位置上有多个字符串的话,就⽤多选结构。出现的次数不确定的话,就⽤量词。对出现的位置有要求的话,就⽤锚

    2024年02月10日
    浏览(11)
  • 冷启问题目前常见解决方案

    冷启问题目前常见解决方案

    随机冷启 个性化冷启 冷启动保量 冷启动保量,保证每个item曝光的次数一样,实时统计已曝光的次数和要曝光的次数 冷启动结束过滤,如果需曝光的量越大,且越接近冷启结束时间,得分越高,被曝光的概率越大 爬坡保量 实时统计曝光、点击、ctr;ctr越高,曝光越少,得分

    2024年02月11日
    浏览(11)
  • 常见的跨域解决方案

    常见的跨域解决方案: 跨域问题可以分为两种情况: 前端跨域和后端跨域 。以下是针对这两种情况的跨域解决方案: 前端跨域解决方案: JSONP: 适用于前端向不同域名下的服务器请求数据,通过添加回调函数名称来实现跨域数据获取。 CORS: 当前端向服务器请求数据时,

    2024年02月12日
    浏览(13)
  • Java常见Bug解决方案

    Java常见Bug解决方案

    刚开始学习Java语言的小伙伴, 很可能被各种各样的程序bug搞得焦头烂额, 甚至被劝退。别怕,健哥将手把手带你了解Java中的异常体系, 如何识别Bug以及如何解决Bug。 让我们先来了解下Java中的异常分类, 如下图: Java中的异常分为Error错误和Exception异常两大类 Error错误 : 一般所有

    2024年02月13日
    浏览(7)
  • Hadoop常见异常及其解决方案

    1、Shell$ExitCodeException 现象:运行hadoop job时出现如下异常: 14/07/09 14:42:50 INFO mapreduce.Job: Task Id : attempt_1404886826875_0007_m_000000_1, Status : FAILED Exception from container-launch: org.apache.hadoop.util.Shell E x i t C o d e E x c e p t i o n : o r g . a p a c h e . h a d o o p . u t i l . S h e l l ExitCodeException: org.ap

    2024年02月06日
    浏览(11)
  • RocketMQ常见问题及解决方案

    RocketMQ FAQ 可能原因 1)消费端处理消息发生异常没有捕获或是因为其他原因,没有返回消费状态 解决方案: 消费端捕获异常, 如果需要重试,返回ConsumeConcurrentlyStatus. RECONSUME_LATER , 如果不需要重试,返回ConsumeConcurrentlyStatus. RECONSUME_SUCCESS 可以在消费端增加重试次数判断,

    2023年04月08日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包