在使用官方下载和许可库的设备上启动app时,使用Proguard混淆Android应用程序会导致致命异常

时间:2012-04-22 19:18:18

标签: java android proguard

我试图混淆一个完整的应用程序,它完全用C ++编写,只下载和许可是用java编写的。它可以很好地使用proguard,但是一旦它被混淆,我在手机上启动应用程序时会出现以下错误。

FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.fantasyhaze.rememory/com.fantasyhaze.rememory.Main}: android.database.sqlite.SQLiteException: no such table: MetadataColumns: , while compiling: SELECT APKVERSION,_id,DOWNLOADSTATUS,DOWNLOADFLAGS FROM MetadataColumns LIMIT 1
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1840)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1861)
    at android.app.ActivityThread.access$1500(ActivityThread.java:132)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:150)
    at android.app.ActivityThread.main(ActivityThread.java:4310)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    at dalvik.system.NativeStart.main(Native Method)
    Caused by: android.database.sqlite.SQLiteException: no such table: MetadataColumns: , while compiling: SELECT APKVERSION,_id,DOWNLOADSTATUS,DOWNLOADFLAGS FROM MetadataColumns LIMIT 1
    at android.database.sqlite.SQLiteCompiledSql.native_compile(Native Method)
    at android.database.sqlite.SQLiteCompiledSql.compile(SQLiteCompiledSql.java:92)
    at android.database.sqlite.SQLiteCompiledSql.<init>(SQLiteCompiledSql.java:65)
    at android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:83)
    at android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49)
    at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
    at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1438)
    at android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1406)
    at N.<init>(Unknown Source)
    at N.a(Unknown Source)
    at com.google.android.vending.expansion.downloader.impl.DownloaderService.a(Unknown Source)
    at com.fantasyhaze.rememory.GameActivity.onCreate(Unknown Source)
    at com.fantasyhaze.rememory.Main.onCreate(Unknown Source)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1804)
    ... 11 more

我在proguard.cfg中使用了以下配置

-dontpreverify
-repackageclasses ''
-allowaccessmodification
-optimizations !code/simplification/arithmetic


-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 interface com.google.android.vending.licensing.ILicensingService

-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>;
}

-keepclassmembers public class com.google.android.vending.expansion.downloader.impl.DownloadsDB { 
    public static final java.lang.String * ; 
} 

在构建应用程序时,它会发出一些警告,我不知道在使用play_licensing和play_apk_expansion时如何解决。

-obfuscate:
    [mkdir] Created dir: D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\bin\proguard
      [jar] Building jar: D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\bin\proguard\original.jar
 [proguard] ProGuard, version 4.7
 [proguard] Reading program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\bin\proguard\original.jar]
 [proguard] Reading program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\lib\play_apk_expansion\downloader_library\bin\classes.jar]
 [proguard] Reading program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\lib\play_licensing\library\bin\classes.jar]
 [proguard] Reading program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\lib\play_apk_expansion\zip_file\bin\classes.jar]
 [proguard] Reading program jar [C:\Android\android-sdk\tools\support\annotations.jar]
 [proguard] Reading library jar [C:\Android\android-sdk\platforms\android-15\android.jar]
 [proguard] Preparing output jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\bin\proguard\obfuscated.jar]
 [proguard]   Copying resources from program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\bin\proguard\original.jar]
 [proguard]   Copying resources from program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\lib\play_apk_expansion\downloader_library\bin\classes.jar]
 [proguard] Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [classes.jar:META-INF/MANIFEST.MF])
 [proguard]   Copying resources from program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\lib\play_licensing\library\bin\classes.jar]
 [proguard] Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [classes.jar:META-INF/MANIFEST.MF])
 [proguard]   Copying resources from program jar [D:\SlidersEdgeUniverse\FloWars\CPE\trunk\Rememory\Source\PRO_Android\lib\play_apk_expansion\zip_file\bin\classes.jar]
 [proguard] Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [classes.jar:META-INF/MANIFEST.MF])
 [proguard]   Copying resources from program jar [C:\Android\android-sdk\tools\support\annotations.jar]
 [proguard] Warning: can't write resource [META-INF/MANIFEST.MF] (Duplicate zip entry [annotations.jar:META-INF/MANIFEST.MF])

2 个答案:

答案 0 :(得分:3)

第一个帖子中的错误消息

  

无法启动活动ComponentInfo {com.fantasyhaze.rememory / com.fantasyhaze.rememory.Main}:android.database.sqlite.SQLiteException:没有这样的表:MetadataColumns :,在编译时:SELECT APKVERSION,_id,DOWNLOADSTATUS,DOWNLOADFLAGS来自MetadataColumns LIMIT 1

表示SQLite数据库存在问题,因为缺少必需的表。

我建议用dex2jar反编译APK文件,然后查看带有JD-GUI的Java类文件,找出哪些Java类文件出现错误或已被混淆,导致应用程序崩溃..

根据我的个人经验,Proguard的大多数问题都与某些必要属性被错误地混淆的类或者在混淆过程中刚删除了类的类有关。

之类的陈述
  

-keep public class * extends android.app.Activity

你的proguard.pro文件中的

允许你从Proguard的混淆过程中排除类

答案 1 :(得分:1)

我最近遇到了这个错误,似乎在混淆了代码之后,反射停止了DownloadsDB类的工作。问题源于DownloadsContentDBHelper.onCreate方法内部检索通过反射声明的嵌套类的问题,至少在我的情况下没有返回任何类。

所以我换了

Class<?>[] arrayOfClass = DownloadsDB.class.getDeclaredClasses();

 Class<?>[] arrayOfClass = new Class[] {MetadataColumns.class, DownloadColumns.class};

手动指定所需的类。类字段也可以通过名称访问,因此我指示proguard完全保留类和所有成员:

-keep class com.google.android.vending.expansion.downloader.impl.DownloadsDB* {*;}

这似乎对我有用。