默认Launcher

默认Launcher

1. 简介

1.1 Launcher启动流程

当系统启动Launcher的时候会在ActivityManagerService中去获取Launcher的activity的信息,然后再调用startActivity。在没有设定默认的Launcher,在获取启动Launcher的Intent的时候会进行弹窗选择,弹窗如图1

在这里插入图片描述

图1

选择always后会在将对应的Launcher包名存储成首选项。

1.2 Launcher发生崩溃

当应用发生崩溃时,ActivityManagerService会进行监测,监测到发生崩溃会,就会进行一系列的处理,如打印日志,弹出崩溃弹窗(如图2)等

在这里插入图片描述

图2

在Launcher第一次发生崩溃时AMS就会清除发生Launcher存储的首选项,默认应用数据存储到首选项里的,发生崩溃这时候重启手机就会弹窗图1弹窗选择默认Launcher。

1.3 选择默认应用

Android Q开始,新增 RoleManager、RoleManagerService 等类,通过 RoleManager 设置默认应用取代通过PackageManagerService里添加首选项方式。

具体操作在packages/apps/PermissionController/里,在Settings里设置默认应用就是动态添加PermissionController里的Preference来实现的。

2. 实现当其中一个Launcher发生崩溃自动切换默认Launcher

2.1 目前想法

2.1.1 修改方案

在AMS监测应用发生崩溃处理的地方实现切换默认Launcher

//services/core/java/com/android/server/am/ActivityManagerService.java#handleApplicationCrashInner()
if (processName.equals("com.zwh.simplelauncher")){
   
   
    RoleManager roleManager = (RoleManager)mContext.getSystemService(RoleManager.class);
    Consumer<Boolean> callback = successful -> {
   
   
        if (successful) {
   
   
            android.util.Log.i("simplelauncher", "handleApplicationCrashInner: successful");
        } else {
   
   
            android.util.Log.i("simplelauncher", "handleApplicationCrashInner: error");
        }
    };
    roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, "com.android.Launcher3", r.userId, Process.myUserHandle(), mContext.getMainExecutor(),callback);
}

能够到达效果,并且在重启后不会切换到发生崩溃的Launcher,只能通过Settings里的开关去切换

2.1.2 存在缺陷
  1. 目前使用RoleManager去切换默认应用时需要系统权限,应用三方Launcher无法通过该方式去实现,目前我实现方式是如下,通过去除权限监测部分
//system\packages\modules\Permission\service\java\com\android\role\RoleService.java#addRoleHolderAsUser
public void addRoleHolderAsUser(@NonNull String roleName, @NonNull String packageName,
                @RoleManager.ManageHoldersFlags int flags, @UserIdInt int userId,
                @NonNull RemoteCallback callback) {
   
   
            ......

//            getContext().enforceCallingOrSelfPermission(Manifest.permission.MANAGE_ROLE_HOLDERS,
//                    "addRoleHolderAsUser");
            ......
}
  1. 由于处理应用发生crash的时候会检查是否发生频繁crash(两次crash时间段很短),频繁crash就会弹出应用崩溃弹窗(如图2),这时候Launcher进程也会从新启动,也就会从新弹出Launcher默认选择框,因此还需要处理弹窗部分。

2.2 更新修改地点

2.2.1 修改方案

修改思想:在进行弹窗的时候进行切换Launcher,这个时候可以进行隐藏崩溃弹窗。弹窗在第一次出现crash的时候不会弹窗,会频繁出现crash的时候弹出(也就是一分钟内出现两次crash)

修改代码:

  1. 过滤清楚默认Launcher配置(原因可以看3.2)
if (proc.isHomeProcess() && proc.hasActivities() && (app.info.flags & FLAG_SYSTEM) == 0&&app.processName.equals("com.zwh.SimpleLauncher")) {
   
   
    proc.clearPackagePreferredForHomeActivities();
}
  1. AppErrors#handleShowAppErrorUi
if (proc.processName.equals("com.zwh.simplelauncher")){
   
   
        RoleManager roleManager = (RoleManager)mContext.getSystemService(RoleManager.class);
        Consumer<Boolean> callback = successful -> {
   
   
            if (successful) {
   
   
                android.util.Log.i("simplelauncher", "handleShowAppErrorUi: successful");
            } else {
   
   
                android.util.Log.i("simplelauncher", "handleShowAppErrorUi: error");
            }
        };
        roleManager.addRoleHolderAsUser(RoleManager.ROLE_HOME, proc.processName, proc.userId, Process.myUserHandle(), mContext.getMainExecutor(),callback)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值