【SystemServer】Android 获取AppWidgetManager为空,通过Framework,SystemServer解决问题

2021年8月30日

将系统原生Email添加到软件集成中
烧录机器
点击原生Email闪退

查看报错,详细Log放在文章最后
关键信息:
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘int[] android.appwidget.AppWidgetManager.getAppWidgetIds(android.content.ComponentName)’ on a null object reference
发现是AppWidgetManager为空
最快想到的解决方案,把用到AppWidgetManager的地方注释
(因为目前需求是能跑起来,AppWidgetManager看起来对核心功能影响不大)

过一会想到,为什么我不让AppWidgetManager跑起来呢
想到服务开启在SystemServer
打开源码后

            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)
                || context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) {
                traceBeginAndSlog("StartAppWidgerService");
                mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
                traceEnd();
            }

发现并没有直接的开关boolean能控制
systemserver是去PMS读取消息
PMS是开机时读取各APP Manifest文件
(这样多了一个疑问,AppWidgetManager依赖PMS,那服务的启动肯定有一个顺序

try {
            traceBeginAndSlog("StartServices");
            startBootstrapServices();
            startCoreServices();
            startOtherServices();
            SystemServerInitThreadPool.shutdown();
        } catch (Throwable ex) {

这样看来,确实)
回到第一个代码片

            if (mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)
                || context.getResources().getBoolean(R.bool.config_enableAppWidgetService)) {
                traceBeginAndSlog("StartAppWidgerService");
                mSystemServiceManager.startService(APPWIDGET_SERVICE_CLASS);
                traceEnd();
            }

从第一二行看出,检查
mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)

context.getResources().getBoolean(R.bool.config_enableAppWidgetService)
是否都为空就行
mPackageManager.hasSystemFeature(PackageManager.FEATURE_APP_WIDGETS)看起来要理解PMS的ShasSystemFeature的原理,先溜放过,放后面
context.getResources().getBoolean(R.bool.config_enableAppWidgetService),要去找到这个bool.xml文件
找到了路径是/frameworks/base/core/res/res/values/config.xml
重大发现

    <!-- True if the device requires AppWidgetService even if it does not have
         the PackageManager.FEATURE_APP_WIDGETS feature -->
    <bool name="config_enableAppWidgetService">false</bool>

config_enableAppWidgetService为false
设置为true,编译framework的service模块
导入到机器替换
查看结果
结果:AppWidgerService启动成功,点击进入原生Email不闪退

编译的时候遇到一个坑
编译提示成功,我就把相应的framework文件push到机器
发现现象还是闪退
后面ls -l查看文件修改日期,发现framework等文件都是几天前的
wdf
把out里面的framework整个文件夹删掉,重新编译
重新替换
测试,现象正确

如何编译和替换测试,后面我再用其他文章细说
总结:
1、平时偶尔看一下系统源码是有用的
2、平台开发的诀窍就是快速寻找

大佬提示我,修改vendor里面的overlay里面的配置更好
所以vendor里面的overlay是可以覆盖原来的设置的
就像在自定义SystemUI的mk文件里,加入overlay参数,会覆盖系统原生SystemUI

报错信息
2020-06-01 00:52:36.998 3886-3886/com.android.email E/Email: FLF.setSelectedAccount(null) called! Destroying existing loader.
2020-06-01 00:52:37.037 3886-3886/com.android.email E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.email, PID: 3886
java.lang.RuntimeException: Unable to start receiver com.android.email.provider.WidgetProvider: java.lang.NullPointerException: Attempt to invoke virtual method ‘int[] android.appwidget.AppWidgetManager.getAppWidgetIds(android.content.ComponentName)’ on a null object reference
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3434)
at android.app.ActivityThread.access 1200 ( A c t i v i t y T h r e a d . j a v a : 200 ) a t a n d r o i d . a p p . A c t i v i t y T h r e a d 1200(ActivityThread.java:200) at android.app.ActivityThread 1200(ActivityThread.java:200)atandroid.app.ActivityThreadH.handleMessage(ActivityThread.java:1667)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6738)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:892)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method ‘int[] android.appwidget.AppWidgetManager.getAppWidgetIds(android.content.ComponentName)’ on a null object reference
at com.android.mail.widget.BaseWidgetProvider.getCurrentWidgetIds(BaseWidgetProvider.java:94)
at com.android.mail.widget.BaseWidgetProvider.migrateAllLegacyWidgetInformation(BaseWidgetProvider.java:395)
at com.android.mail.widget.BaseWidgetProvider.onReceive(BaseWidgetProvider.java:123)
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3425)
at android.app.ActivityThread.access 1200 ( A c t i v i t y T h r e a d . j a v a : 200 ) a t a n d r o i d . a p p . A c t i v i t y T h r e a d 1200(ActivityThread.java:200) at android.app.ActivityThread 1200(ActivityThread.java:200)atandroid.app.ActivityThreadH.handleMessage(ActivityThread.java:1667)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:6738)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:892)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 12 SystemServer 的启动流程如下: 1. 引导加载:系统启动时,先加载引导程序,进行硬件初始化、内核加载等操作。 2. Zygote 进程启动:Zygote 是 Android 系统中的一个特殊进程,负责孵化其他应用进程。Zygote 进程会预加载一些常用的类和资源,以加快应用的启动速度。 3. SystemServer 进程启动:Zygote 进程会 fork 出 SystemServer 进程,该进程是 Android 系统中的核心服务进程。SystemServer 进程负责启动和管理系统级别的服务,例如 ActivityManagerService、PackageManagerService、WindowManagerService 等。 4. SystemServer 初始化:SystemServer 进程启动后,会进行一系列的初始化操作。首先会创建 Looper 线程,用于接收消息并处理各个服务的初始化工作。然后依次创建各个系统服务,并调用它们的启动方法。 5. 启动系统服务:SystemServer 进程会按照一定顺序启动各个系统服务。每个系统服务都有自己的初始化流程,例如 PackageManagerService 会加载应用程序列表、数据目录等;ActivityManagerService 会初始化进程间通信机制等。 6. 启动应用进程:在系统服务启动完成后,SystemServer 进程会通过 Zygote 孵化出其他应用进程。应用进程会根据 AndroidManifest.xml 中的配置进行初始化,包括创建 Application、加载资源等。 总结来说,Android 12 SystemServer 的启动流程包括引导加载、Zygote 进程启动、SystemServer 进程启动、SystemServer 初始化、启动系统服务和启动应用进程等步骤。这些步骤都是为了在系统启动时提供必要的服务和资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值