5

Recentemente ho migrato il mio progetto Android da Eclipse ad Android Studio.Android Studio - Le regole di 'mantenimento' di Proguard vengono ignorate?

La versione di debug dell'app creata da Android Studio funziona correttamente su un dispositivo, ma la versione di rilascio si arresta in modo anomalo all'avvio.

Ecco build.gradle fascicolo di mio app:

apply plugin: 'com.android.application' 
apply plugin: 'com.google.gms.google-services' 

android { 
    compileSdkVersion 23 
    buildToolsVersion "23.0.2" 

    defaultConfig { 
     applicationId "com.example.myapp" 
     minSdkVersion 15 
     targetSdkVersion 23 
     versionCode 49 
     versionName "1.3.1" 
    } 
    buildTypes { 
     release { 
      minifyEnabled true 
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 
     } 
    } 
    packagingOptions { 
     //exclude 'META-INF/DEPENDENCIES' 
     exclude 'META-INF/NOTICE' 
     exclude 'META-INF/LICENSE' 
     exclude 'META-INF/LICENSE.txt' 
     exclude 'META-INF/NOTICE.txt' 
    } 
} 

dependencies { 
    compile fileTree(dir: 'libs', include: ['*.jar']) 
    testCompile 'junit:junit:4.12' 
    compile 'com.android.support:appcompat-v7:23.1.1' 
    compile 'com.android.support:design:23.1.1' 
    compile 'com.android.support:support-v13:23.1.1' 
    compile 'org.apache.httpcomponents:httpmime:4.2.3' 
    compile 'org.twitter4j:twitter4j-core:4.0.2' 
    compile 'com.facebook.android:facebook-android-sdk:4.8.2' 
    compile 'ch.acra:acra:4.7.0' 
    compile 'com.google.android.gms:play-services-analytics:8.3.0' 
    compile 'com.google.android.gms:play-services-ads:8.3.0' 
    compile 'com.google.android.gms:play-services-plus:8.3.0' 
    //compile 'com.google.android.gms:play-services:8.3.0' 
    compile 'com.google.android.gms:play-services-gcm:8.3.0' 
} 

Ecco il mio proguard-rules.pro di file:

# Add project specific ProGuard rules here. 
# By default, the flags in this file are appended to flags specified 
# in P:\Program Files\Android\sdk/tools/proguard/proguard-android.txt 
# You can edit the include path and order by changing the proguardFiles 
# directive in build.gradle. 
# 
# For more details, see 
# http://developer.android.com/guide/developing/tools/proguard.html 

# Add any project specific keep options here: 

# If your project uses WebView with JS, uncomment the following 
# and specify the fully qualified class name to the JavaScript interface 
# class: 
#-keepclassmembers class fqcn.of.javascript.interface.for.webview { 
# public *; 
#} 



# 
# My Classes - start 
# 

-keep public class com.example.myapp.SplashActivity 
-keep public class com.example.myapp.FragmentActivityWithListener 
-keep public class com.example.myapp.AbstractHelpActivity 
-keep public class com.example.myapp.GetContentFromWebTask$CompletedListener 
# Don't rename the MenuBuilder filename as this is referenced in our AbstractHelpActivity.java file 
-keep public class android.support.v7.internal.view.menu.MenuBuilder 
-keep class android.support.v7.widget.ShareActionProvider { *; } 

# 
# My Classes - end 
# 


# 
# Twitter library - start 
# 

-dontwarn twitter4j.** 
-keep class twitter4j.** { *; } 

# 
# Twitter library - end 
# 


# 
# Google Play Service library - start 
# 

-keep class * extends java.util.ListResourceBundle { 
    protected Object[][] getContents(); 
} 

-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable { 
    public static final *** NULL; 
} 

-keepnames @com.google.android.gms.common.annotation.KeepName class * 
-keepclassmembernames class * { 
    @com.google.android.gms.common.annotation.KeepName *; 
} 

-keepnames class * implements android.os.Parcelable { 
    public static final ** CREATOR; 
} 

# 
# Google Play Service library - end 
# 


# 
# ACRA - start 
# 

#ACRA specifics 
# Restore some Source file names and restore approximate line numbers in the stack traces, 
# otherwise the stack traces are pretty useless 
-keepattributes SourceFile,LineNumberTable 

# ACRA needs "annotations" so add this... 
# Note: This may already be defined in the default "proguard-android-optimize.txt" 
# file in the SDK. If it is, then you don't need to duplicate it. See your 
# "project.properties" file to get the path to the default "proguard-android-optimize.txt". 
-keepattributes *Annotation* 

# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'. 
# Note: if you are removing log messages elsewhere in this file then this isn't necessary 
-keep class org.acra.ACRA { 
    *; 
} 

# keep this around for some enums that ACRA needs 
-keep class org.acra.ReportingInteractionMode { 
    *; 
} 

-keepnames class org.acra.sender.HttpSender$** { 
    *; 
} 

-keepnames class org.acra.ReportField { 
    *; 
} 

# keep this otherwise it is removed by ProGuard 
-keep public class org.acra.ErrorReporter { 
    public void addCustomData(java.lang.String,java.lang.String); 
    public void putCustomData(java.lang.String,java.lang.String); 
    public void removeCustomData(java.lang.String); 
} 

# keep this otherwise it is removed by ProGuard 
-keep public class org.acra.ErrorReporter { 
    public void handleSilentException(java.lang.Throwable); 
} 

# 
# ACRA - end 
# 


# 
# Facebook - start 
# 
-keep class com.facebook.** { *; } 
-keepattributes Signature 
# 
# Facebook - end 
# 

Ecco la traccia dello stack:

01-06 11:48:58.313 27667-27667/? E/ACRA: ACRA caught a RuntimeException for com.example.myapp 
    java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.example.myapp/com.example.myapp.SplashActivity}: java.lang.ClassNotFoundException: Didn't find class "com.example.myapp.SplashActivity" on path: DexPathList[[zip file "/data/app/com.example.myapp-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]] 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2650) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2873) 
     at android.app.ActivityThread.access$900(ActivityThread.java:181) 
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1482) 
     at android.os.Handler.dispatchMessage(Handler.java:102) 
     at android.os.Looper.loop(Looper.java:145) 
     at android.app.ActivityThread.main(ActivityThread.java:6145) 
     at java.lang.reflect.Method.invoke(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:372) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 
     Caused by: java.lang.ClassNotFoundException: Didn't find class "com.example.myapp.SplashActivity" on path: DexPathList[[zip file "/data/app/com.example.myapp-1/base.apk"],nativeLibraryDirectories=[/vendor/lib, /system/lib]] 
     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:511) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:469) 
     at android.app.Instrumentation.newActivity(Instrumentation.java:1079) 
     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2640) 
     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2873)  
     at android.app.ActivityThread.access$900(ActivityThread.java:181)  
     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1482)  
     at android.os.Handler.dispatchMessage(Handler.java:102)  
     at android.os.Looper.loop(Looper.java:145)  
     at android.app.ActivityThread.main(ActivityThread.java:6145)  
     at java.lang.reflect.Method.invoke(Native Method)  
     at java.lang.reflect.Method.invoke(Method.java:372)  
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)  
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)  
     Suppressed: java.lang.NoClassDefFoundError: com.example.myapp.SplashActivity 
     at dalvik.system.DexFile.defineClassNative(Native Method) 
     at dalvik.system.DexFile.defineClass(DexFile.java:226) 
     at dalvik.system.DexFile.loadClassBinaryName(DexFile.java:219) 
     at dalvik.system.DexPathList.findClass(DexPathList.java:321) 
     at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:54) 
       ... 14 more 
     Suppressed: java.lang.ClassNotFoundException: com.example.myapp.SplashActivity 
     at java.lang.Class.classForName(Native Method) 
     at java.lang.BootClassLoader.findClass(ClassLoader.java:781) 
     at java.lang.BootClassLoader.loadClass(ClassLoader.java:841) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:504) 
       ... 13 more 
     Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack available 
01-06 11:48:58.363 27667-27667/? E/ACRA: Not adding buildConfig to log. Class Not found : com.example.myapp.BuildConfig. Please configure 'buildConfigClass' in your ACRA config 
01-06 11:48:58.453 27667-27691/? E/ACRA: ACRA caught a InternalError for com.example.myapp 
    java.lang.InternalError: Thread starting during runtime shutdown 
     at java.lang.Thread.nativeCreate(Native Method) 
     at java.lang.Thread.start(Thread.java:1063) 
     at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920) 
     at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1336) 
     at com.android.okhttp.ConnectionPool.get(ConnectionPool.java:211) 
     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:109) 
     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:368) 
     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:296) 
     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:399) 
     at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:110) 
     at org.acra.e.b.a(HttpRequest.java:122) 
     at org.acra.sender.HttpSender.a(HttpSender.java:245) 
     at org.acra.af.a(SendWorker.java:181) 
     at org.acra.af.a(SendWorker.java:140) 
     at org.acra.af.run(SendWorker.java:76) 
01-06 11:48:58.483 27667-27691/? E/ACRA: Not adding buildConfig to log. Class Not found : com.example.myapp.BuildConfig. Please configure 'buildConfigClass' in your ACRA config 
01-06 11:48:58.503 27667-27691/? E/AndroidRuntime: FATAL EXCEPTION: Thread-2863 
       Process: com.example.myapp, PID: 27667 
       java.lang.InternalError: Thread starting during runtime shutdown 
        at java.lang.Thread.nativeCreate(Native Method) 
        at java.lang.Thread.start(Thread.java:1063) 
        at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:920) 
        at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1336) 
        at com.android.okhttp.ConnectionPool.get(ConnectionPool.java:211) 
        at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:109) 
        at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:368) 
        at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:296) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:399) 
        at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:110) 
        at org.acra.e.b.a(HttpRequest.java:122) 
        at org.acra.sender.HttpSender.a(HttpSender.java:245) 
        at org.acra.af.a(SendWorker.java:181) 
        at org.acra.af.a(SendWorker.java:140) 
        at org.acra.af.run(SendWorker.java:76) 
01-06 11:48:58.503 1038-1476/? W/ActivityManager: Force finishing activity com.example.myapp/.SplashActivity 

così sembra le keep regole Ho specificato nel mio proguard-rules.pro f non vengono utilizzati come classe com.example.myapp.SplashActivity impossibile trovare.

Ho controllato la pagina Android Developers ProGuard e sembra che ho impostato tutto correttamente, quindi non ho idea del motivo per cui non funziona.

Qualcuno può consigliare cosa devo fare per finire con un apk offuscato che funziona?

+2

Grazie, ma non credo di avere un problema DexIndexOverflowException (?) –

risposta

1

ho trovato il problema. E 'stato nel file di build.gradle del mio progetto:

// Top-level build file where you can add configuration options common to all sub-projects/modules. 

buildscript { 
    repositories { 
     jcenter()  // This is the default repo 
     mavenCentral() // This is the Maven Central repo 
    } 
    dependencies { 
     classpath 'com.android.tools.build:gradle:1.3.0' 
     classpath 'com.google.gms:google-services:1.5.0-beta2' 

     // NOTE: Do not place your application dependencies here; they belong 
     // in the individual module build.gradle files 
    } 
} 

allprojects { 
    repositories { 
     jcenter()  // This is the default repo 
     mavenCentral() // This is the Maven Central repo 
    } 
} 

task clean(type: Delete) { 
    delete rootProject.buildDir 
} 

La soluzione era quella di cambiare il classpath 'com.android.tools.build:gradle:1.3.0' a classpath 'com.android.tools.build:gradle:1.5.0'.

(Ho scoperto questo con la creazione di un nuovo progetto di test e confrontando i valori nei rispettivi file build.gradle.)

Per inciso, il contenuto del mio file proguard-rules.pro ora è solo ...

# 
# Twitter - start 
# 

-dontwarn twitter4j.** 
-keep class twitter4j.** { *; } 

# 
# Twitter - end 
# 


# 
# Support library/ShareActionProvider - start 
# 

-keep class android.support.v7.internal.** { *; } 
-keep interface android.support.v7.internal.** { *; } 
-keep class android.support.v7.** { *; } 
-keep interface android.support.v7.** { *; } 

# 
# Support library/ShareActionProvider - start 
# 


# 
# ACRA - start 
# 

#ACRA specifics 
# Restore some Source file names and restore approximate line numbers in the stack traces, 
# otherwise the stack traces are pretty useless 
-keepattributes SourceFile,LineNumberTable 

# ACRA needs "annotations" so add this... 
# Note: This may already be defined in the default "proguard-android-optimize.txt" 
# file in the SDK. If it is, then you don't need to duplicate it. See your 
# "project.properties" file to get the path to the default "proguard-android-optimize.txt". 
-keepattributes *Annotation* 

# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'. 
# Note: if you are removing log messages elsewhere in this file then this isn't necessary 
-keep class org.acra.ACRA { 
    *; 
} 

# keep this around for some enums that ACRA needs 
-keep class org.acra.ReportingInteractionMode { 
    *; 
} 

-keepnames class org.acra.sender.HttpSender$** { 
    *; 
} 

-keepnames class org.acra.ReportField { 
    *; 
} 

# keep this otherwise it is removed by ProGuard 
-keep public class org.acra.ErrorReporter { 
    public void addCustomData(java.lang.String,java.lang.String); 
    public void putCustomData(java.lang.String,java.lang.String); 
    public void removeCustomData(java.lang.String); 
} 

# keep this otherwise it is removed by ProGuard 
-keep public class org.acra.ErrorReporter { 
    public void handleSilentException(java.lang.Throwable); 
} 

# 
# ACRA - end 
# 

... quindi non avevo bisogno di molte delle mie vecchie direttive o di quelle suggerite da Dhawal nella sua risposta.

NB - Capisco che le direttive ACRA non saranno richieste a partire da ACRA 4.8.

0

non utilizzare -keep public class com.example.myapp.SplashActivity

rimuovere tutte le righe per il file Proguard e utilizzare sotto modo, utilizzando questo Proguard non cambiare il nome della classe della vostra app (aggiungere di seguito le linee dipendere dal vostro requisito come la vostra applicazione non ha il fornitore di contenuti rimuove quindi quella linea).

-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.app.backup.BackupAgentHelper 
-keep public class * extends android.preference.Preference 
-keep public class com.android.vending.licensing.ILicensingService 
-keep class org.xmlpull.v1.** { *; } 
-dontnote com.android.vending.licensing.ILicensingService 

leggere questo: how to use proguard in android app

+0

Grazie per questo. Ho anche dovuto aggiungere '-davwarn twitter4j. **' e '-keep class twitter4j. ** {*; } 'per l'app da compilare, ma ho ancora lo stesso problema in fase di esecuzione. Ho anche aggiunto '-keep public class * estende android.support.v7.app.AppCompatActivity' (che SplashActivity è il diretto discendente di) per ogni evenienza, ma che non ha aiutato. –

+0

Ho anche cambiato la riga nel file build.gradle della mia app in 'proguardFiles getDefaultProguardFile ('proguard-android-optimize.txt'), 'proguard-rules.pro'' ma questo non ha fatto nessuna differenza. Sembra che il mio file proguard-rules.pro non venga elaborato ... –

+0

NB - Ho eseguito un test rapido (introducendo un errore di sintassi nel mio file proguard-rules.pro e ho visto l'errore quando provo a generare il APK firmato, quindi so che il mio file proguard-rules.pro è stato sicuramente letto. –