问题描述
|
我找到了一个在VM中安装Android-x86的简单指南(指南)。
与Eclipse的连接均正常,但在VM上安装我的应用程序失败,并出现以下错误:
06-21 22:40:26.390: INFO/PackageManager(2439): /data/app/xyz.apk changed; unpacking
06-21 22:40:26.390: ERROR/PackageManager(2439): Package xyz has mismatched uid: 10044 on disk,10045 in settings
06-21 22:40:26.390: WARN/PackageManager(2439): Native ABI mismatch from package file
06-21 22:40:26.390: WARN/PackageManager(2439): Package Couldn\'t be installed in /data/app/xyz-1.apk
我在Google上搜索了错误,并找到了一个小的Python脚本来解决此问题,但是它不起作用(脚本)。执行脚本后,我得到了同样的错误。
我使用的是Android-x86 2.2泛型,可在此处找到更多详细信息:2.2版
有可能解决该问题吗?
编辑:
我测试了所有2.2版本。一般而言,只有通用和斯巴达才能工作,但没人接受我的apk。
也尝试过adb install <packagefile>
。
编辑2:
我尝试了@Vlad的建议工具。对apk签名后,它部分起作用。最后,我使用了apkTools并将apkEdit的旧文件替换为apktool中的新文件。
但是使用adb的安装会挂起消息,等待设备或什么都没有。如果我相信eclipse DDMS,则每次我尝试安装apk时,与设备的连接都会丢失。
这是我尝试安装常规apk时的失败:Failure [INSTALL_Failed_INVALID_APK]
解决方法
由存在的文件夹
/data/data/xyz/
引起的错误Package xyz has mismatched uid: 10044 on disk,10045 in settings
。
在此消息文件夹中,该文件夹与现在安装的文件夹(10045)具有不同的所有者(10044)。这是由先前的不干净安装引起的。
例如,先前的安装因某些错误而失败,因此请不要删除创建的文件夹。
因为在文件夹中可以是来自其他应用程序的数据,Android不允许使用它。 PackageManager
尝试以不同的方式修复它,但如果不能这样做-它会为应用获取不同的目录并显示此消息。
更好的解决方案-安装应用程序并将其清除干净。之后,再次安装。
另一种解决方案-以某些方式删除文件夹/data/data/xyz/
。可能您为此需要root。
5英镑的代码(评论可能会很有帮助):
// This is a normal package,need to make its data directory.
dataPath = getDataPathForPackage(pkg.packageName,0);
boolean uidError = false;
if (dataPath.exists()) {
// XXX should really do this check for each user.
mOutPermissions[1] = 0;
FileUtils.getPermissions(dataPath.getPath(),mOutPermissions);
// If we have mismatched owners for the data path,we have a problem.
if (mOutPermissions[1] != pkg.applicationInfo.uid) {
boolean recovered = false;
if (mOutPermissions[1] == 0) {
// The directory somehow became owned by root. Wow.
// This is probably because the system was stopped while
// installd was in the middle of messing with its libs
// directory. Ask installd to fix that.
int ret = mInstaller.fixUid(pkgName,pkg.applicationInfo.uid,pkg.applicationInfo.uid);
if (ret >= 0) {
recovered = true;
String msg = \"Package \" + pkg.packageName
+ \" unexpectedly changed to uid 0; recovered to \" +
+ pkg.applicationInfo.uid;
reportSettingsProblem(Log.WARN,msg);
}
}
if (!recovered && ((parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
|| (scanMode&SCAN_BOOTING) != 0)) {
// If this is a system app,we can at least delete its
// current data so the application will still work.
int ret = mInstaller.remove(pkgName,0);
if (ret >= 0) {
// TODO: Kill the processes first
// Remove the data directories for all users
sUserManager.removePackageForAllUsers(pkgName);
// Old data gone!
String prefix = (parseFlags&PackageParser.PARSE_IS_SYSTEM) != 0
? \"System package \" : \"Third party package \";
String msg = prefix + pkg.packageName
+ \" has changed from uid: \"
+ mOutPermissions[1] + \" to \"
+ pkg.applicationInfo.uid + \"; old data erased\";
reportSettingsProblem(Log.WARN,msg);
recovered = true;
// And now re-install the app.
ret = mInstaller.install(pkgName,pkg.applicationInfo.uid);
if (ret == -1) {
// Ack should not happen!
msg = prefix + pkg.packageName
+ \" could not have data directory re-created after delete.\";
reportSettingsProblem(Log.WARN,msg);
mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
return null;
}
// Create data directories for all users
sUserManager.installPackageForAllUsers(pkgName,pkg.applicationInfo.uid);
}
if (!recovered) {
mHasSystemUidErrors = true;
}
} else if (!recovered) {
// If we allow this install to proceed,we will be broken.
// Abort,abort!
mLastScanError = PackageManager.INSTALL_FAILED_UID_CHANGED;
return null;
}
if (!recovered) {
pkg.applicationInfo.dataDir = \"/mismatched_uid/settings_\"
+ pkg.applicationInfo.uid + \"/fs_\"
+ mOutPermissions[1];
pkg.applicationInfo.nativeLibraryDir = pkg.applicationInfo.dataDir;
String msg = \"Package \" + pkg.packageName
+ \" has mismatched uid: \"
+ mOutPermissions[1] + \" on disk,\"
+ pkg.applicationInfo.uid + \" in settings\";
// writer
synchronized (mPackages) {
mSettings.mReadMessages.append(msg);
mSettings.mReadMessages.append(\'\\n\');
uidError = true;
if (!pkgSetting.uidError) {
reportSettingsProblem(Log.ERROR,msg);
}
}
}
}
pkg.applicationInfo.dataDir = dataPath.getPath();
, 您的应用程序似乎使用了本机代码。你使用NDK吗?
一种检查方法是使用
“ apktool转储标记”
参见http://ibotpeaches.github.io/Apktool/
寻找类似的东西
本机代码:\'armeabi \'
在输出中
,
该问题与名为“ dexopt”的程序有关,该程序确定
在计算机上安装的应用程序的固定大小的缓冲区,称为\“ LinearAlloc \”
特定设备。缓冲区大小为8或16 MB时(较新)
Android版本,例如Ice Cream Sandwich和Jelly Bean,仅5 MB
在旧版本中。
当您对apk签名时,您可能会执行proguard步骤,从而删除未引用的代码部分(类,方法,字段等)。因此,您传递了与缓冲区大小相关的错误。
但是proguard并非每次都能提供解决方案,您仍然有可能超过缓冲区大小限制。
Facebook为此提供了一个解决方案:“将我们的应用分成多个dex文件”。参见:https://www.facebook.com/notes/facebook-engineering/under-the-hood-dalvik-patch-for-facebook-for-android/10151345597798920