在已签名的应用程序中写入包裹异常

Posted

技术标签:

【中文标题】在已签名的应用程序中写入包裹异常【英文标题】:Writing exception to parcel in signed application 【发布时间】:2014-06-24 22:47:33 【问题描述】:

我在我的 android 应用程序中尝试了一种非常奇怪的行为,并且无法在 *** 或其他任何地方找到解决方案。

从 Eclipse 加载到手机时,我有一个 Android 应用程序可以正常工作且没有错误。但是当签名时,我在 Logcat 中看到了这个错误:

E/DatabaseUtils(2360): Writing exception to parcel
E/DatabaseUtils(2360): java.lang.SecurityException: Permission Denial: get/set setting for user asks to run as user -2 but is calling from user 0; this requires android.permission.INTERACT_ACROSS_USERS_FULL
E/DatabaseUtils(2360):  at com.android.server.am.ActivityManagerService.handleIncomingUser(ActivityManagerService.java:13140)
E/DatabaseUtils(2360):  at android.app.ActivityManager.handleIncomingUser(ActivityManager.java:2038)
E/DatabaseUtils(2360):  at com.android.providers.settings.SettingsProvider.callFromPackage(SettingsProvider.java:607)
E/DatabaseUtils(2360):  at android.content.ContentProvider$Transport.call(ContentProvider.java:279)
E/DatabaseUtils(2360):  at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:273)
E/DatabaseUtils(2360):  at android.os.Binder.execTransact(Binder.java:388)
E/DatabaseUtils(2360):  at dalvik.system.NativeStart.run(Native Method)

然后:

E/Parcel(2360): Class not found when unmarshalling: com.meapp.utilites.Anuncio
E/Parcel(2360): java.lang.ClassNotFoundException: com.meapp.utilites.Anuncio
E/Parcel(2360):     at java.lang.Class.classForName(Native Method)
E/Parcel(2360):     at java.lang.Class.forName(Class.java:204)
E/Parcel(2360):     at java.lang.Class.forName(Class.java:169)
E/Parcel(2360):     at android.os.Parcel.readParcelableCreator(Parcel.java:2091)
E/Parcel(2360):     at android.os.Parcel.readParcelable(Parcel.java:2055)
E/Parcel(2360):     at android.os.Parcel.readValue(Parcel.java:1971)
E/Parcel(2360):     at android.os.Parcel.readMapInternal(Parcel.java:2255)
E/Parcel(2360):     at android.os.Bundle.unparcel(Bundle.java:223)
E/Parcel(2360):     at android.os.Bundle.getString(Bundle.java:1082)
E/Parcel(2360):     at android.content.Intent.getStringExtra(Intent.java:4961)
E/Parcel(2360):     at com.android.server.am.ActivityStack.startActivityLocked(ActivityStack.java:3761)
E/Parcel(2360):     at com.android.server.am.ActivityStack.startActivityMayWait(ActivityStack.java:4977)
E/Parcel(2360):     at com.android.server.am.ActivityManagerService.startActivityAsUser(ActivityManagerService.java:3173)
E/Parcel(2360):     at com.android.server.am.ActivityManagerService.startActivity(ActivityManagerService.java:3129)
E/Parcel(2360):     at android.app.ActivityManagerNative.onTransact(ActivityManagerNative.java:157)
E/Parcel(2360):     at com.android.server.am.ActivityManagerService.onTransact(ActivityManagerService.java:2125)
E/Parcel(2360):     at android.os.Binder.execTransact(Binder.java:388)
E/Parcel(2360):     at dalvik.system.NativeStart.run(Native Method)
E/Parcel(2360): Caused by: java.lang.NoClassDefFoundError: com/meapp/utilites/Anuncio
E/Parcel(2360):     ... 18 more
E/Parcel(2360): Caused by: java.lang.ClassNotFoundException: Didn't find class "com.meapp.utilites.Anuncio" on path: .
E/Parcel(2360):     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:64)
E/Parcel(2360):     at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
E/Parcel(2360):     at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
E/Parcel(2360):     ... 18 more

我在我的应用程序中使用 proguard,并添加了这些行以确保 com.meapp.utilites.Anuncio 可见:

-keep class com.meapp.utilites.**  *; 
-keep class * implements android.os.Parcelable  *; 
-keep public class com.meapp.utilites.Anuncio

com.meapp.utilites.Anuncio 实现 Parcelable。

但对我来说最奇怪的是,即使在 ClassNotFoundException 没有“捕获”之后,应用程序也能正常工作。更重要的是,该应用程序的工作方式就像 Parcelable 被毫无问题地恢复一样,因为它使用了该对象中包含的数据。

所以我有几个问题:

    为什么在我签名的应用程序中给我一个 Permission denial 但在未签名的应用程序中没有问题?

    为什么我的应用在 ClassNotFound 之后不崩溃...?

    为什么工作正常却报错?

    如何解决这个问题并让 proguard 让我的班级可见?

感谢您的帮助,我认为这是 Android Ninjas 的问题...

【问题讨论】:

我也面临同样的问题。你有什么收获吗? @AtulOHolic 相关***.com/questions/19756727/… @OneWay - 我添加了该权限,但没有帮助。还有其他解决方案吗? 你读过答案下面的 cmets 吗? 是的,我做到了,它只是说它超出了限制。 【参考方案1】:

我在 6 个月前遇到了这个问题,所以我不得不在 bitbucket 中搜索以查看我为使其正常工作所做的更改。

我所做的是使用此模板作为基础更改我的脚本 proguard-project.txt:

# Basic Template extracted from http://wiebe-elsinga.com/blog/obfuscating-for-android-with-proguard/
-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic
-keepattributes *Annotation*

-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider

-keep public class * extends android.view.View 
    public <init>(android.content.Context);
    public <init>(android.content.Context, android.util.AttributeSet);
    public <init>(android.content.Context, android.util.AttributeSet, int);
    public void set*(...);


-keepclasseswithmembers class * 
    public <init>(android.content.Context, android.util.AttributeSet);


-keepclasseswithmembers class * 
    public <init>(android.content.Context, android.util.AttributeSet, int);


-keepclassmembers class * implements android.os.Parcelable 
    static android.os.Parcelable$Creator CREATOR;


-keepclassmembers class **.R$* 
    public static <fields>;

您可以在http://wiebe-elsinga.com/blog/obfuscating-for-android-with-proguard/找到更多信息

如您所见,与 Parcelable 相关,我的原始脚本遗漏了部分配置:

-keepclassmembers class * implements android.os.Parcelable 
static android.os.Parcelable$Creator CREATOR;

我希望这对你们所有人都有帮助@AtulOHolic 和@OneWay

【讨论】:

【参考方案2】:

android.permission.INTERACT_ACROSS_USERS_FULL 是签名级别的权限。除非它与系统具有相同的签名,否则您的应用将无法使用它。

class not found 可能是由于包问题,请确保您为启动活动提供了与包名相同的包名。

希望这会有所帮助

【讨论】:

【参考方案3】:

在将 Parceble 与 progaurd 一起使用时,您又错过了一步。 您可以查看this。

对于你的情况,在 progaurd 文本文件中添加这一行

  -keep class * implements android.os.Parcelable  
   public static final android.os.Parcelable$Creator *; 

【讨论】:

以上是关于在已签名的应用程序中写入包裹异常的主要内容,如果未能解决你的问题,请参考以下文章

Android:在已部署的应用程序中找不到资源异常

面向对象

面向对象

应用认领(重写将签名写入空包)

为啥要尝试在已检查的异常上抛出未检查的异常? [复制]

python pandas在已存在的excel中追加数据