异常信息
- 使用 adb 命令安装应用时,安装失败输出如下错误信息:
> adb install "C:\Users\Downloads\itmob.cn.apk"
Performing Streamed Install
adb: failed to install itmob.cn.apk: Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package cn.itmob.demo tried to change user cn.itmob.demo.uid]
- 在 Android Studio 中使用 Gradle 执行安装命令时,输出如下错误信息:
> Task :app:installDebug
Installing APK 'app-debug.apk' on 'Pixel_3a' for :app:debug
Unable to install C:\Users\WorkSpace\Demo\app\build\outputs\apk\debug\app-debug.apk
com.android.ddmlib.InstallException: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package cn.itmob.demo tried to change user null
at com.android.ddmlib.internal.DeviceImpl.installRemotePackage(DeviceImpl.java:1373)
at com.android.ddmlib.internal.DeviceImpl.installPackage(DeviceImpl.java:1199)
...
at java.base@11.0.15/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base@11.0.15/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base@11.0.15/java.lang.Thread.run(Thread.java:829)
> Task :app:installDebug FAILED
FAILURE: Build failed with an exception.
* What went wrong:
Execution failed for task ':app:installDebug'.
> java.util.concurrent.ExecutionException: com.android.builder.testing.api.DeviceException: com.android.ddmlib.InstallException: INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package cn.itmob.demo tried to change user null
解决方法:
Android 中每个应用默认都以单独的进程运行在单独的虚拟机上,每个进程都由单独的Linux用户创建,系统默认给每个app分配一个 uid,如果两个应用设置了相同的 uid,且应用的签名相同,则它们就能运行在同一个进程中,能够互相共享数据。
出现异常的原因:
-
设置了 uid,但是签名不同
当我们想通过将 Manifest 中的
android:sharedUserId
设置为 android.uid.system 来让应用运行在系统进程获取系统权限时,如果只是设置了相同的 uid,但是签名与系统应用不同时安装应用就会出现上面的异常信息。- 如果是用于获取系统权限,使用与系统应用相同的签名即可解决。
- 不是用于获取系统权限,两个普通应用设置相同 uid 也要确保签名相同
-
uid 发生了变化
我遇到的问题是之前安装的版本未设置 android:sharedUserId 但是新安装的版本设置了 uid,因为 uid 发生变化,无法完成安装。
- 卸载重新安装来解决,
如果应用已经发布,需要更新 uid 貌似没有更好的办法(没遇到过这种情况也没去了解,因为 android 10 API 级别 29 开始 android:sharedUserId 已经弃用)
API 级别 29(Android 10)中
android:sharedUserId
已弃用
共享用户 ID 会在软件包管理器中导致具有不确定性的行为。因此强烈建议您不要使用它,并且在未来的 Android 版本中会将其移除。应用程序应使用适当的通信机制(例如:服务和 content provider),在共享组件间实现互操作性。
请注意,现有应用无法移除此值,因为不支持不使用共享用户 ID。这类应用应添加android:sharedUserMaxSdkVersion=”32”
,以免在新用户安装时使用共享 ID。
上面的介绍来自官网文档:https://developer.android.com/guide/topics/manifest/manifest-element#uid
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:sharedUserId="cn.itmob.demo.uid"
android:sharedUserMaxSdkVersion="32">
...
</manifest>