当前位置: 移动技术网 > 移动技术>移动开发>Android > Android记录一次InstallerPackage apk报错的问题分析

Android记录一次InstallerPackage apk报错的问题分析

2020年07月17日  | 移动技术网移动技术  | 我要评论

前言

 	测试这两天给我提了一个BUG,说把APK放内部储存里面,然后点击安装的时候,软件安装包程序停止运行!纳尼!原生的啊。我肯定没有动过
07-01 17:43:29.120  3257  3295 E AndroidRuntime: FATAL EXCEPTION: InstallThread
07-01 17:43:29.120  3257  3295 E AndroidRuntime: Process: com.android.packageinstaller, PID: 3257
07-01 17:43:29.120  3257  3295 E AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.AppOpsManager.checkPackage(int, java.lang.String)' on a null object reference
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:1690)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.os.Parcel.readException(Parcel.java:1637)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.content.pm.IPackageInstaller$Stub$Proxy.createSession(IPackageInstaller.java:249)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.content.pm.PackageInstaller.createSession(PackageInstaller.java:297)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at com.android.packageinstaller.InstallAppProgress.doPackageStage(InstallAppProgress.java:295)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at com.android.packageinstaller.InstallAppProgress.-wrap2(InstallAppProgress.java)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at com.android.packageinstaller.InstallAppProgress$5.run(InstallAppProgress.java:396)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.os.Handler.handleCallback(Handler.java:836)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.os.Handler.dispatchMessage(Handler.java:103)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.os.Looper.loop(Looper.java:203)
07-01 17:43:29.120  3257  3295 E AndroidRuntime: 	at android.os.HandlerThread.run(HandlerThread.java:61)

z

分析

撸起袖子改BUG,对于程序员而言,这还得了啊,对于用户也是体验极差的
1.可以看到报错地方时在createSession的时候出错了。跟踪代码就是PackageInstallerService.java中的createSession 在具体点就是

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.app.AppOpsManager.checkPackage(int, java.lang.String)' on a null object reference

这一段。然后我们在

 private int createSessionInternal(SessionParams params, String installerPackageName, int userId)
            throws IOException {
        final int callingUid = Binder.getCallingUid();
        mPm.enforceCrossUserPermission(callingUid, userId, true, true, "createSession");

        if (mPm.isUserRestricted(userId, UserManager.DISALLOW_INSTALL_APPS)) {
            throw new SecurityException("User restriction prevents installing");
        }

        if ((callingUid == Process.SHELL_UID) || (callingUid == Process.ROOT_UID)) {
            params.installFlags |= PackageManager.INSTALL_FROM_ADB;

        } else {
            mAppOps.checkPackage(callingUid, installerPackageName);//这里打LOG看看是哪个空指针了

            params.installFlags &= ~PackageManager.INSTALL_FROM_ADB;
            params.installFlags &= ~PackageManager.INSTALL_ALL_USERS;
            params.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
        }

        // Only system components can circumvent runtime permissions when installing.
        if ((params.installFlags & PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS) != 0
                && mContext.checkCallingOrSelfPermission(Manifest.permission
                .INSTALL_GRANT_RUNTIME_PERMISSIONS) == PackageManager.PERMISSION_DENIED) {
            throw new SecurityException("You need the "
                    + "android.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS permission "
                    + "to use the PackageManager.INSTALL_GRANT_RUNTIME_PERMISSIONS flag");
        }
        .......省略
}

得出结论是 mAppOps 为空 。这个玩意是什么请百度,AppOpsManager;
2.这个初始化的地方是在

    public void systemReady() {
        mAppOps = mContext.getSystemService(AppOpsManager.class);
    }

于是加了LOG发现他确实没有走systemReady()方法,所以怎么说这个为空很正常

3.继续跟踪代码发现,他是在PackageManagerService.java中的systemReady()中调用的

    @Override
    public void systemReady() {
    .......
            // If we upgraded grant all default permissions before kicking off.
        for (int userId : grantPermissionsUserIds) {
            mDefaultPermissionPolicy.grantDefaultPermissions(userId);
        }

        // If we did not grant default permissions, we preload from this the
        // default permission exceptions lazily to ensure we don't hit the
        // disk on a new user creation.
        if (grantPermissionsUserIds == EMPTY_INT_ARRAY) {
            mDefaultPermissionPolicy.scheduleReadDefaultPermissionExceptions();
        }

        // Kick off any messages waiting for system ready
        if (mPostSystemReadyMessages != null) {
            for (Message msg : mPostSystemReadyMessages) {
                msg.sendToTarget();
            }
            mPostSystemReadyMessages = null;
        }

        // Watch for external volumes that come and go over time
        final StorageManager storage = mContext.getSystemService(StorageManager.class);
        storage.registerListener(mStorageListener);
	Slog.w("tuliyuan---PKMS"," SYSTEM READY "+(mInstallerService==null));
        mInstallerService.systemReady();
        mPackageDexOptimizer.systemReady();

    ..........

很奇怪这里为什么没走,也没有return函数啊,未必pkms的systemReady没走?于是找到启动PKMS的地方SystemServer.java 搜索systemReady
发现

        try {
	    Log.i("tuliyuan---systemserver", "=== mPackageManagerService systemReady ===");
            mPackageManagerService.systemReady();
        } catch (Throwable e) {
            reportWtf("making Package Manager Service ready", e);
        }

有个try catch…
心里咯噔一下。不会吧不会吧不会吧? pkms哪里报错了只是崩溃捕获了?
adb reboot;adb logcat -b all > log.txt一看 果然。。。

07-01 17:19:15.925  1113  1113 E SystemServer: BOOT FAILURE making Package Manager Service ready
07-01 17:19:15.925  1113  1113 E SystemServer: java.lang.NullPointerException: Attempt to read from field 'java.util.ArrayList android.content.pm.PackageParser$Package.requestedPermissions' on a null object reference
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.pm.DefaultPermissionGrantPolicy.grantRuntimePermissionsLPw(DefaultPermissionGrantPolicy.java:892)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.pm.DefaultPermissionGrantPolicy.grantRuntimePermissionsLPw(DefaultPermissionGrantPolicy.java:882)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.pm.DefaultPermissionGrantPolicy.grantDefaultSystemHandlerPermissions(DefaultPermissionGrantPolicy.java:601)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.pm.DefaultPermissionGrantPolicy.grantDefaultPermissions(DefaultPermissionGrantPolicy.java:220)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.pm.PackageManagerService.systemReady(PackageManagerService.java:19041)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.SystemServer.startOtherServices(SystemServer.java:1553)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.SystemServer.run(SystemServer.java:420)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.server.SystemServer.main(SystemServer.java:292)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at java.lang.reflect.Method.invoke(Native Method)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1084)
07-01 17:19:15.925  1113  1113 E SystemServer: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:945)

根据LOG得知是 上面过滤默认权限的时候报错了

然后 找到了该死的错误

		
		 PackageParser.Package baidu_location = getSystemPackageLPr("com.baidu.map.location");

		grantRuntimePermissionsLPw(baidu_location, STORAGE_PERMISSIONS, userId);
	     grantRuntimePermissionsLPw(baidu_location, PHONE_PERMISSIONS, userId);
		 
                 

这个baidulocation已经不要了!没有内置,然后找不到包 就错了。。。所以

		 PackageParser.Package baidu_location = getSystemPackageLPr("com.baidu.map.location");
		 if(baidu_location != null){
		 	grantRuntimePermissionsLPw(baidu_location, STORAGE_PERMISSIONS, userId);
	         	grantRuntimePermissionsLPw(baidu_location, PHONE_PERMISSIONS, userId);
		 }

这样就好了

总结

别忘了判断一下空指针异常!!!

本文地址:https://blog.csdn.net/qq_18906227/article/details/107376111

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网