【问题标题】:Proguard: App crashes after obfuscatingProguard:混淆后应用程序崩溃
【发布时间】:2014-02-27 14:21:12
【问题描述】:

我以前没有使用过 ProGuard,所以我可能在这里忽略了一些东西。

问题如下:我必须混淆我的 Android Studio 项目。我克服了构建问题,能够在测试设备上运行我的发布构建(启用了 proguard)。该应用程序启动,一旦我按下登录按钮,它就会崩溃。 Logcat 给出以下错误输出:

E/AndroidRuntime﹕ FATAL EXCEPTION: main
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.packagename/com.packagename.activity.MainWebActivity}: android.view.InflateException: Binary XML file line #48: Error inflating class fragment
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2295)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
            at android.app.ActivityThread.access$700(ActivityThread.java:159)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: android.view.InflateException: Binary XML file line #48: Error inflating class fragment
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:719)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
            at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:361)
            at android.app.Activity.setContentView(Activity.java:1956)
            at com.packagename.activity.MainWebActivity.onCreate(Unknown Source)
            at android.app.Activity.performCreate(Activity.java:5372)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
            at android.app.ActivityThread.access$700(ActivityThread.java:159)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
            at dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
            at com.packagename.fragment.DrawerMenuFragment.a(Unknown Source)
            at com.packagename.fragment.DrawerMenuFragment.onCreateView(Unknown Source)
            at android.support.v4.app.Fragment.performCreateView(Unknown Source)
            at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
            at android.support.v4.app.FragmentManagerImpl.moveToState(Unknown Source)
            at android.support.v4.app.FragmentManagerImpl.addFragment(Unknown Source)
            at android.support.v4.app.FragmentActivity.onCreateView(Unknown Source)
            at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:691)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:761)
            at android.view.LayoutInflater.rInflate(LayoutInflater.java:769)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:498)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:398)
            at android.view.LayoutInflater.inflate(LayoutInflater.java:354)
            at com.android.internal.policy.impl.PhoneWindow.setContentView(PhoneWindow.java:361)
            at android.app.Activity.setContentView(Activity.java:1956)
            at com.packagename.activity.MainWebActivity.onCreate(Unknown Source)
            at android.app.Activity.performCreate(Activity.java:5372)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1104)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2257)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2349)
            at android.app.ActivityThread.access$700(ActivityThread.java:159)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5419)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1187)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
            at dalvik.system.NativeStart.main(Native Method)

在 LoginActivity 之后,应用会启动一个 WebView 活动,该活动包含 DrawerLayout。我的 proguard-project.txt 如下所示:

-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keepattributes *Annotation*


-keep public class * extends android.app.Activity
-keep public class * extends android.support.v4.app.FragmentActivity
-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.preference.Preference
-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*(...);
}

# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}

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

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

-keepclassmembers class * extends android.content.Context {
    public void *(android.view.View);
    public void *(android.view.MenuItem);
}

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

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

-keepclasseswithmembernames class * {
    native <methods>;
}
-keepclassmembers class * {
    public void *ButtonClicked(android.view.View);
}

-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment

-keepclassmembers public class * extends android.view.View {
      void set*(***);
      *** get*();
    }

-libraryjars libs

# The official support library.
-keep class android.support.v4.** { *; }
-keep interface android.support.v4.** { *; }

# Facebook library
-keep class com.facebook.** {
   *;
}

-dontwarn com.squareup.okhttp.**

# Make sure that Google Analytics doesn't get removed
-keep class com.google.analytics.tracking.android.CampaignTrackingReceiver

# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.** { *; } 

我怀疑我的 proguard-project.txt 中缺少某些内容。我知道这是混淆的问题,因为当我添加 -dontobfuscate 时,它​​会正常运行。

我在这里错过了什么?

编辑:我能够通过添加发现发生了什么 -keepattributes SourceFile,LineNumberTable 就我而言,它与用户模型有关。

【问题讨论】:

    标签: android obfuscation proguard


    【解决方案1】:

    这很可能有一些使用自定义命名空间的 xml 属性,例如:

    app:fragment="com.example.app.myFragment"
    

    aapt 不会选择,所以你必须自己添加这些规则:

    -keep public class * extends android.app.Fragment {
        <init>(...);
    }
    -keep public class * extends android.support.v4.app.Fragment {
        <init>(...);
    }
    

    【讨论】:

    • 感谢您的回答!不幸的是,除了已经被排除在外的 facebook LoginButton,我没有使用任何自定义命名空间
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-10
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多