ITmob-Ly
发布于 2023-07-20 / 248 阅读
0

Android Exception: Failure [INSTALL_FAILED_SHARED_USER_INCOMPATIBLE: Package tried to change user]

异常信息

  1. 使用 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]
  1. 在 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,且应用的签名相同,则它们就能运行在同一个进程中,能够互相共享数据

出现异常的原因:

  1. 设置了 uid,但是签名不同

    当我们想通过将 Manifest 中的 android:sharedUserId 设置为 android.uid.system 来让应用运行在系统进程获取系统权限时,如果只是设置了相同的 uid,但是签名与系统应用不同时安装应用就会出现上面的异常信息。

    • 如果是用于获取系统权限,使用与系统应用相同的签名即可解决。
    • 不是用于获取系统权限,两个普通应用设置相同 uid 也要确保签名相同
  2. 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>