adb安装应用失败

前言
Android Debug Bridge (ADB) 是一个功能强大的命令行工具,用于与 Android 设备通信。
安装 APK 文件:
- 使用命令
adb install <apk文件路径>
可以将 APK 文件安装到设备上。 - 如果需要覆盖安装,可以使用
adb install -r <apk文件路径>
。 - 如果需要降级安装,可以使用
adb install -d <apk文件路径>
。 - 想要在安装时自动授予权限,可以使用
adb install -g <apk文件路径>
。
调试android应用的过程, 突然出现安装失败的问题, 检查了各种环境, 重启了开发工具和目标设备依然无法解决.
平台
名称 | 信息 |
---|---|
Android | 7.1 |
主控 | RK3288 |
主机 | Ubuntu 20.04 |
AndroidStudio | Build #AI-241.15989.150.2411.11948838, built on June 11, 2024 Runtime version: 17.0.10+0-17.0.10b1087.21-11609105 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. |
adb | Android Debug Bridge version 1.0.41 Version 35.0.2-12147458 |
安装失败现象
在AndroidStudio中尝试失败后, 又使用终端输入命令尝试:
bash
adb install -r ~/adb/apk/Muzei.apk
Performing Streamed Install
adb: failed to install /home/xxx/adb/apk/Muzei.apk:
Exception occurred while executing:
java.lang.IllegalStateException: Too many active sessions for UID 2000
at com.android.server.pm.PackageInstallerService.createSessionInternal(PackageInstallerService.java:523)
at com.android.server.pm.PackageInstallerService.createSession(PackageInstallerService.java:420)
at com.android.server.pm.PackageManagerShellCommand.doCreateSession(PackageManagerShellCommand.java:1380)
at com.android.server.pm.PackageManagerShellCommand.runInstall(PackageManagerShellCommand.java:201)
at com.android.server.pm.PackageManagerShellCommand.onCommand(PackageManagerShellCommand.java:109)
at android.os.ShellCommand.exec(ShellCommand.java:96)
at com.android.server.pm.PackageManagerService.onShellCommand(PackageManagerService.java:22745)
at android.os.Binder.shellCommand(Binder.java:594)
at android.os.Binder.onTransact(Binder.java:492)
at android.content.pm.IPackageManager$Stub.onTransact(IPackageManager.java:2679)
at com.android.server.pm.PackageManagerService.onTransact(PackageManagerService.java:3804)
at android.os.Binder.execTransact(Binder.java:697)
从LOG中可以看到关键的报错信息:Too many active sessions for UID 2000
:
按图索骥可以在对应的源码目录下查到LOG的源头:
frameworks/base/services/core/java/com/android/server/pm/PackageInstallerService.java
java
final int sessionId;
final PackageInstallerSession session;
synchronized (mSessions) {
// Sanity check that installer isn't going crazy
final int activeCount = getSessionCount(mSessions, callingUid);
if (mContext.checkCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES)
== PackageManager.PERMISSION_GRANTED) {
if (activeCount >= MAX_ACTIVE_SESSIONS_WITH_PERMISSION) {
throw new IllegalStateException(
"Too many active sessions for UID " + callingUid);
}
} else if (activeCount >= MAX_ACTIVE_SESSIONS_NO_PERMISSION) {
throw new IllegalStateException(
"Too many active sessions for UID " + callingUid);
}
final int historicalCount = mHistoricalSessionsByInstaller.get(callingUid);
if (historicalCount >= MAX_HISTORICAL_SESSIONS) {
throw new IllegalStateException(
"Too many historical sessions for UID " + callingUid);
}
sessionId = allocateSessionIdLocked();
}
private static int getSessionCount(SparseArray<PackageInstallerSession> sessions,
int installerUid) {
int count = 0;
final int size = sessions.size();
for (int i = 0; i < size; i++) {
final PackageInstallerSession session = sessions.valueAt(i);
if (session.getInstallerUid() == installerUid) {
count++;
}
}
return count;
}
java
@GuardedBy("mSessions")
private void writeSessionsLocked() {
if (LOGD) Slog.v(TAG, "writeSessionsLocked()");
FileOutputStream fos = null;
try {
fos = mSessionsFile.startWrite();
XmlSerializer out = new FastXmlSerializer();
out.setOutput(fos, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, TAG_SESSIONS);
final int size = mSessions.size();
for (int i = 0; i < size; i++) {
final PackageInstallerSession session = mSessions.valueAt(i);
session.write(out, mSessionsDir);
}
out.endTag(null, TAG_SESSIONS);
out.endDocument();
mSessionsFile.finishWrite(fos);
} catch (IOException e) {
if (fos != null) {
mSessionsFile.failWrite(fos);
}
}
}
从代码中可以看到, 安装的过程中, 系统会记录下对应UID的安装数量等信息.
于是可以从设备端中查看记录的内容: /data/system/install_sessions.xml
java
rk3288:/data/system # cat install_sessions.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<sessions>
<session sessionId="4538363" userId="0" installerUid="2000" createdMillis="1358505151252" sessionStageDir="/data/app/vmdl4538363.tmp" prepared="true" sealed="false" mode="1" installFlags="4150" installLocation="1" sizeBytes="-1" originatingUid="-1" installRason="0" />
<session sessionId="12795577" userId="0" installerUid="2000" createdMillis="1358499734290" sessionStageDir="/data/app/vmdl12795577.tmp" prepared="true" sealed="false" mode="1" installFlags="4150" installLocation="1" sizeBytes="-1" originatingUid="-1" installRason="0" />
<session sessionId="13071720" userId="0" installerUid="2000" createdMillis="1358502763745" sessionStageDir="/data/app/vmdl13071720.tmp" prepared="true" sealed="false" mode="1" installFlags="4150" installLocation="1" sizeBytes="-1" originatingUid="-1" installRason="0" />
<session sessionId="13187387" userId="0" installerUid="2000" createdMillis="1358519315394" sessionStageDir="/data/app/vmdl13187387.tmp" prepared="true" sealed="false" mode="1" installFlags="4150" installLocation="1" sizeBytes="-1" originatingUid="-1" installRason="0" />
<session sessionId="14248417" userId="0" installerUid="2000" createdMillis="1358518925167" sessionStageDir="/data/app/vmdl14248417.tmp" prepared="true" sealed="false" mode="1" installFlags="4150" installLocation="1" sizeBytes="-1" originatingUid="-1" installRason="0" />
<session sessionId="16520263" userId="0" installerUid="2000" createdMillis="1358506871037" sessionStageDir="/data/app/vmdl16520263.tmp" prepared="true" sealed="false" mode="1" installFlags="4150" installLocation="1" sizeBytes="-1" originatingUid="-1" installRason="0" />
....
文件的内容很多, 这里只摘取了一部分.
回到源码中, 可以看到配置的SESSION 数量: 1024
java
/** Upper bound on number of active sessions for a UID that has INSTALL_PACKAGES */
private static final long MAX_ACTIVE_SESSIONS_WITH_PERMISSION = 1024;
/** Upper bound on number of active sessions for a UID without INSTALL_PACKAGES */
private static final long MAX_ACTIVE_SESSIONS_NO_PERMISSION = 50;
也就是说, 这个问题是因为使用ADB安装应用的次数超过了1024个
解决
- 有权限的情况下, 修改或删除 /data/system/install_sessions.xml 的内容, 重启后即可
- 没有权限恢复出厂设置, 清除数据即可.