Android--应用安装卸载失败问题分析

1、应用安装失败:does not include classes.dex

08-04 17:15:23.118W/dalvikvm( 5253): DexOptZ:zip archive '/data/app/***.cloneit-1.apk' does not include classes.dex

08-04 17:15:23.118W/installd(  266): DexInv:--- END '/data/app/***cloneit-1.apk' --- status=0xff00, process failed

08-04 17:15:23.118E/installd(  266): dexopt in='/data/app/***.cloneit-1.apk'out='/data/dalvik-cache/data@app@***[email protected]'res=65280

。。。。。。

08-04 17:15:23.288D/CP_PackageInstaller( 5020): installed code msg.what = 1

08-04 17:15:23.288I/CP_PackageInstaller( 5020): installed codemsg.arg1 = -11

 

这个是因为安装的apk里面没有classes.dex文件,安装失败。

安装应用时,包含在apk文件里的dex文件会在运行时通过dexopt进行优化,优化后的文件将保存在缓存中(data/dalvik-cache)。因此,安装后生成的apk文件是不可以直接安装的,缺少了classes.dex文件。

2、卸载失败:PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER

这种卸载失败,最直接的获知方法是通过打印的日志:W/PackageManager( 5729): Not removing package *****: has active device admin
卸载应用时,会调用到PackageManagerService的deletePackageX方法,代码如下:
    private int deletePackageX(String packageName, int userId, int flags) {
        final PackageRemovedInfo info = new PackageRemovedInfo();
        final boolean res;

        final UserHandle removeForUser = (flags & PackageManager.DELETE_ALL_USERS) != 0
                ? UserHandle.ALL : new UserHandle(userId);

        if (isPackageDeviceAdmin(packageName, removeForUser.getIdentifier())) {
            Slog.w(TAG, "Not removing package " + packageName + ": has active device admin");
            return PackageManager.DELETE_FAILED_DEVICE_POLICY_MANAGER;
        }
    private boolean isPackageDeviceAdmin(String packageName, int userId) {
        IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));
        try {
            if (dpm != null) {
                if (dpm.isDeviceOwner(packageName)) {
                    return true;
                }
                int[] users;
                if (userId == UserHandle.USER_ALL) {
                    users = sUserManager.getUserIds();
                } else {
                    users = new int[]{userId};
                }
                for (int i = 0; i < users.length; ++i) {
                    if (dpm.packageHasActiveAdmins(packageName, users[i])) {
                        return true;
                    }
                }
            }
        } catch (RemoteException e) {
        }
        return false;
    }
卸载程序要调IDevicePolicyManager服务里(在DevicePolicyManagerService.java里实现)的packageHasActiveAdmins()函数检查是否具备admin权限,如果没有admin权限,则直接返回不卸载程序,有了admin才去卸载程序,删除程序数据,发送广播消息(Intent.ACTION_PACKAGE_REMOVE或Intent.ACTION_UID_REMOVE),修改packages.xml文件等。因此一些应用程序安装后运行时,需要激活设备管理权限,卸载时必须取消激活设备管理器才可卸载。

你可能感兴趣的:(Android系统)