关闭

android 4.4以下loadIocn nullpointerException问题

标签: android
392人阅读 评论(0) 收藏 举报
分类:

之前一直没注意,今天有同学跟我说在oppo n1手机上获取apk安装包时会崩溃,看到的崩溃信息是

java.lang.NullPointerException
    at android.app.ActivityThread$ResourcesKey.<init>(ActivityThread.java:2200)
    at android.app.ActivityThread.getTopLevelResources(ActivityThread.java:187)
    at android.app.ActivityThread.getTopLevelResources(ActivityThread.java:246)
    at android.app.ContextImpl$ApplicationPackageManager.getResourcesForApplication(ContextImpl.java:2188)
    at android.app.ContextImpl$ApplicationPackageManager.getDrawable(ContextImpl.java:2114)
    at android.content.pm.PackageItemInfo.loadIcon(PackageItemInfo.java:131)
    at android.app.ContextImpl$ApplicationPackageManager.getApplicationIcon(ContextImpl.java:2169)
    at com.metago.astro.IconManager.loadPackageIcon(IconManager.java:330)

从异常信息可以看出是在ResourcesKey的构造时崩溃的。找到4.2的该类定义

    ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration, float scale) {
1516            mResDir = resDir;
1517            mDisplayId = displayId;
1518            if (overrideConfiguration != null) {
1519                if (Configuration.EMPTY.equals(overrideConfiguration)) {
1520                    overrideConfiguration = null;
1521                }
1522            }
1523            mOverrideConfiguration = overrideConfiguration;
1524            mScale = scale;
1525            int hash = 17;
1526            hash = 31 * hash + mResDir.hashCode();
1527            hash = 31 * hash + mDisplayId;
1528            hash = 31 * hash + (mOverrideConfiguration != null
1529                    ? mOverrideConfiguration.hashCode() : 0);
1530            hash = 31 * hash + Float.floatToIntBits(mScale);
1531            mHash = hash;

可以看到类在构造时没有对resDir进行校验,在第1526行引用时就可能报空指针问题
而我一直使用的note3并未出现此问题,于是再看到4.4上这个类的定义

31    public More ...ResourcesKey(String resDir, int displayId, Configuration overrideConfiguration,
32            float scale, IBinder token) {
33        mResDir = resDir;
34        mDisplayId = displayId;
35        if (overrideConfiguration != null) {
36            mOverrideConfiguration.setTo(overrideConfiguration);
37        }
38        mScale = scale;
39        mToken = token;
40
41        int hash = 17;
42        hash = 31 * hash + (mResDir == null ? 0 : mResDir.hashCode());
43        hash = 31 * hash + mDisplayId;
44        hash = 31 * hash + (mOverrideConfiguration != null
45                ? mOverrideConfiguration.hashCode() : 0);
46        hash = 31 * hash + Float.floatToIntBits(mScale);
47        mHash = hash;
48    }

看到4.4中的42行在引用时进行了判空,所以并没有崩溃。这种情况下获取到的icon都是默认的,也就是安卓那个小绿机器人。
解决这个问题的办法是在获取了apk安装包的applicationInfo后,

applicationInfo.sourceDir = "apkpath";
applicationInfo.publicSourceDir = "apkpath";

把这apk的路径赋予这两个值任意之一就行,因为从activityThread.java可以看到,resDir取的就是sourceDir和publicSourceDir之一。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:82867次
    • 积分:1199
    • 等级:
    • 排名:千里之外
    • 原创:34篇
    • 转载:5篇
    • 译文:0篇
    • 评论:6条
    文章分类
    最新评论