在 Android 应用程序中使用 MultiDex 运行 ProGuard 两次,只有第二次出现警告/注释?

Posted

技术标签:

【中文标题】在 Android 应用程序中使用 MultiDex 运行 ProGuard 两次,只有第二次出现警告/注释?【英文标题】:Using MultiDex in Android App runs ProGuard twice and only second time with Warnings/Notes? 【发布时间】:2016-01-18 02:10:06 【问题描述】:

我在我的 android 应用中使用 MultiDex 和 ProGuard。当我运行我的应用程序时,结果证明 proguard 运行了两次。以下是 proguard 运行之后的任务:

:app:transformClassesAndResourcesWithProguardForRelease
ProGuard, version 5.2.1
...
Initializing...
Shrinking...
Obfuscating...
Writing output...

及以后:

:app:transformClassesWithMultidexlistForRelease
ProGuard, version 5.2.1

这是我的应用程序的build.gradle 文件:

buildscript 
    repositories 
        maven  url 'https://maven.fabric.io/public' 
    

    dependencies 
        classpath 'io.fabric.tools:gradle:1.20.1'
    


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


android 
    compileSdkVersion 23
    buildToolsVersion "23.0.1"

    defaultConfig 
        applicationId "de.majestella"
        minSdkVersion 16
        targetSdkVersion 22
        versionCode 3
        versionName "1.0.1"

        // Enabling multidex support.
        multiDexEnabled true
    

    dexOptions 
        incremental true
        javaMaxHeapSize "2g"
    


    buildTypes 
        debug 
            debuggable true

            // ProGuard
            minifyEnabled false
        
        release 
                signingConfig signingConfigs.release

                debuggable false

                // ProGuard
                minifyEnabled true
                proguardFiles getDefaultProguardFile('proguard-android.txt'),
                        'proguard-rules.pro', 'proguard-guava.pro', 'proguard-square-picasso.pro',
                        'proguard-crashlytics.pro', 'proguard-google-analytics.pro'

       

    



repositories 
    mavenCentral()
    maven 
        name = "sonatype"
        url = "https://oss.sonatype.org/content/repositories/snapshots/"
    
    maven 
        name = "sonatypeGoogle"
        url = "https://oss.sonatype.org/content/repositories/google-snapshots/"
    
    flatDir 
        dirs 'libs'
    
    maven  url 'https://maven.fabric.io/public' 



dependencies 
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.0.1'
    compile 'com.android.support:design:23.0.1'


    compile('com.crashlytics.sdk.android:crashlytics:2.5.2@aar') 
        transitive = true;
    

    compile 'com.android.support:multidex:1.0.1'

    compile 'com.google.android.gms:play-services-analytics:8.1.0'
    compile "com.google.android.gms:play-services:8.1.0"


在第一次 proguard 运行之后(即,在 :app:transformClassesAndResourcesWithProguardForRelease 之后)我在 writing output 之后收到以下警告,所以 proguard 本身在我的规则下可以正常工作:

Warning: can't write resource [fabric/com.crashlytics.sdk.android.answers.properties] (Duplicate zip entry [fabric/com.crashlytics.sdk.android.answers.properties])
Warning: can't write resource [fabric/com.crashlytics.sdk.android.beta.properties] (Duplicate zip entry [fabric/com.crashlytics.sdk.android.beta.properties])
Warning: can't write resource [fabric/com.crashlytics.sdk.android.crashlytics-core.properties] (Duplicate zip entry [fabric/com.crashlytics.sdk.android.crashlytics-core.properties])
Warning: can't write resource [fabric/com.crashlytics.sdk.android.crashlytics.properties] (Duplicate zip entry [fabric/com.crashlytics.sdk.android.crashlytics.properties])
Warning: can't write resource [fabric/io.fabric.sdk.android.fabric.properties] (Duplicate zip entry [fabric/io.fabric.sdk.android.fabric.properties])

:app:transformClassesWithMultidexlistForRelease 之后发生第二次 proguard 运行时,我得到以下信息:

Note: android.support.design.widget.CoordinatorLayout calls 'Class.getAnnotation'
Note: com.google.ads.mediation.MediationServerParameters calls 'Field.getAnnotation'
Note: com.google.common.eventbus.AnnotatedSubscriberFinder calls 'Method.getAnnotation'
Note: com.google.common.reflect.Invokable$MethodInvokable calls 'Method.getParameterAnnotations'
Note: d.a.a.a.c calls 'Class.getAnnotation'
Note: d.a.a.a.i calls 'Class.getAnnotation'
Note: android.support.v4.app.ak calls 'Field.getType'
Note: com.google.android.gms.internal.zzsf calls 'Field.getType'
...

这很奇怪,因为在第一次运行 proguard 时,由于我的规则,我没有收到这样的警告/注释。

这是我的 ProGuard 规则:

-keep class com.google.common.io.Resources 
    public static <methods>;

-keep class com.google.common.collect.Lists 
    public static ** reverse(**);

-keep class com.google.common.base.Charsets 
    public static <fields>;

-keep class com.google.common.collect.MapMakerInternalMap$ReferenceEntry
-keep class com.google.common.cache.LocalCache$ReferenceEntry

-dontwarn sun.misc.Unsafe
-dontwarn com.google.common.collect.MinMaxPriorityQueue
-keepattributes SourceFile,LineNumberTable,*Annotation*
-keep class com.crashlytics.android.**



-dontwarn com.squareup.okhttp.**

-dontnote org.apache.http.conn.**
-dontnote org.apache.http.params.**
-dontnote android.net.http.**

-dontnote **ILicensingService
-dontnote com.android.vending.billing.IInAppBillingService


-dontwarn com.google.auto.factory.**

-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,*Annotation*,EnclosingMethod


-dontnote android.support.**
-dontnote com.google.common.util.concurrent.**
-dontnote com.squareup.okhttp.**

-keep class org.jsoup.**  *; 
-keeppackagenames org.jsoup.nodes
-keep class com.google.common.cache.Striped64  *; 
-keep class com.google.common.**  *; 
-keep class com.daimajia.slider.**  *; 


-dontnote org.jsoup.**
-dontnote com.google.common.**
-keep class com.squareup.picasso.**  *; 
-keep class com.google.android.gms.**  *; 
-keep class com.google.ads.**  *; 
-keep class com.lorentzos.**  *; 
-keep public class com.google.android.gms.*  public *; 
-dontwarn com.google.android.gms.**

-dontnote com.google.android.gms.maps.internal.CreatorImpl

-keep class com.mikepenz.iconics.**  *; 

在我看来,第二次 ProGuard 运行没有使用我的 proguard 规则。

编辑:这是gradlew -q tasks --all的结果:https://gist.github.com/confile/2a15d80980214656f4f1

为什么第二次 Proguard 运行会引发错误,我该如何解决?

【问题讨论】:

我在您的问题中没有看到 ProGuard 的任何错误,只有“注释”。 尝试运行gradlew -q tasks --all 找出它的来源。它将列出所有任务及其依赖项。 (将输出写入文件可能很有用,以便于搜索。) @kevinpelgrims 我应该搜索什么? 您应该能够找到它运行 ProGuard 任务的位置。如果它位于两个完全不同的地方,您也许能够弄清楚如何禁用其中一个。 @kevinpelgrims 我没有更改任何默认的 Android 构建过程。是否属于multi dex? 【参考方案1】:

似乎是android gradle插件问题。看到这个https://www.google.co.kr/url?sa=t&source=web&rct=j&url=https://groups.google.com/forum/m/%23!topic/adt-dev/iS_lyRH8hL8&ved=0ahUKEwiP7cP-nMHJAhXLp5QKHX3qBuwQFggdMAI&usg=AFQjCNF4ZuCA79SeCltd8kBIzArzeBbKsQ&sig2=UFqfkY_By7z1rCW4SwmQZw

【讨论】:

请发布答案而不是链接。

以上是关于在 Android 应用程序中使用 MultiDex 运行 ProGuard 两次,只有第二次出现警告/注释?的主要内容,如果未能解决你的问题,请参考以下文章

bugly使用问题记录

如何在 android 应用程序中使用 OSM 地图。?有啥教程可以学习在android中使用OSM吗?

我可以在 sencha 应用程序(Android)中使用 android AsyncTask

在 Android Studio 中使用 ActivityInstrumentationTestCase2 在横向测试 Android 应用程序

如何在 Android 应用程序中使用自定义主题

在 Android 12 中使用 WorkManager