解决Android4.4.4报错:requires com.huawei.android.launcher.permission.WRITE_SETTINGS:

引言

项目之前对于机型测试过一次,但是没有对 Android 4.X 版本进行测试,这周有同事在用这款手机,出现的问题是:点击桌面图标提示“XXX已停止运行”。

问题排查

通过下面的 Log 信息

reading com.huawei.android.launcher.LauncherProvider from pid=721,uid=10079 requires com.huawei.android.launcher.permission.WRITE_SETTINGS: uid 10079 does not have com.huawei.android.launcher.permission.WRITE_SETTINGS

发现问题:
没有声明这个权限:

<uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/>

这里需要注意区分该权限和原生系统的权限

<uses-permission android:name="android.permission.WRITE_SETTINGS" />

此时,编译通过,运行又会报下面这个错:

java.lang.RuntimeException: Unable to get provider com.google.firebase.provider.FirebaseInitProvider: java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.provider.FirebaseInitProvider" on path: DexPathList[[zip file "/data/app/com.xxx-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx-2, /vendor/lib, /system/lib, /data/datalib]]
                                                                     at android.app.ActivityThread.installProvider(ActivityThread.java:5087)
                                                                     at android.app.ActivityThread.installContentProviders(ActivityThread.java:4673)
                                                                     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4613)
                                                                     at android.app.ActivityThread.access$1800(ActivityThread.java:141)
                                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298)
                                                                     at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                     at android.os.Looper.loop(Looper.java:136)
                                                                     at android.app.ActivityThread.main(ActivityThread.java:5336)
                                                                     at java.lang.reflect.Method.invokeNative(Native Method)
                                                                     at java.lang.reflect.Method.invoke(Method.java:515)
                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871)
                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
                                                                     at dalvik.system.NativeStart.main(Native Method)
                                                                  Caused by: java.lang.ClassNotFoundException: Didn't find class "com.google.firebase.provider.FirebaseInitProvider" on path: DexPathList[[zip file "/data/app/com.xxx-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.xxx-2, /vendor/lib, /system/lib, /data/datalib]]
                                                                     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
                                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
                                                                     at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
                                                                     at android.app.ActivityThread.installProvider(ActivityThread.java:5072)
                                                                     at android.app.ActivityThread.installContentProviders(ActivityThread.java:4673) 
                                                                     at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4613) 
                                                                     at android.app.ActivityThread.access$1800(ActivityThread.java:141) 
                                                                     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1298) 
                                                                     at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                     at android.os.Looper.loop(Looper.java:136) 
                                                                     at android.app.ActivityThread.main(ActivityThread.java:5336) 
                                                                     at java.lang.reflect.Method.invokeNative(Native Method) 
                                                                     at java.lang.reflect.Method.invoke(Method.java:515) 
                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:871) 
                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 
                                                                     at dalvik.system.NativeStart.main(Native Method) 

很明显这两次的错误信息不一样,但是这次的是什么原因引起的呢?这有需要进一步排查了。

分析

虽然第一个权限问题找到了解决方案,但却不是根本原因。因为项目已经在 Android5.X,Android6.X,Android7.X,Android 8.0 和 Android8.1 上没有出现这个问题。那么肯定就是有什么东西在 Android5.0 的时候是一个分界线,所以才会导致这个问题出现,因为我在 Android4.4 的模拟器上测试也是同样的问题,所以并不是机型问题。

进一步排查

发现项目中使用了下面这个东西

multiDexEnabled true

这个我们都知道起作用(方法数 64K 限制),下面看重点(原因)

Android 5.0 之前版本的 Dalvik 可执行文件不支持分包

Android 5.0之前的版本使用 Dalvik 来执行应用代码。默认情况下,Dalvik 限制应用的每个 APK 只能使用单个 classes.dex 字节码文件

而Android 5.0 及更高版本的 Dalvik 可执行文件支持分包

Android 5.0及更高版本使用名为 ART 的运行时,后者原生支持从 APK 文件加载多个 DEX 文件。ART 在应用安装时执行预编译,扫描 classesN.dex 文件,并将它们编译成单个 .oat 文件,供 Android 设备执行。

问题所在

因为使用了突破方法数限制功能,所以项目的 Application 中需要做初始化,但是经检查,并未做如下初始化工作,因此结合上面的知识点,才会在 Android4.X 出现此错误。

@Override
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(base);
}

总结

  • 开始的权限问题只是表象,根本原因是后面的缺少配置问题
  • 之所以出现这样的情况,是因为 Dalvik 可执行文件是否支持分包有一个版本分界线问题
  • 二次开发别人写过的项目,要使用颠覆性的想象来解决想不到的意外。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

code小生

有头像,我们容易成为朋友

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值