ProGuard 导致应用滞后

Posted

技术标签:

【中文标题】ProGuard 导致应用滞后【英文标题】:ProGuard causes lag of application 【发布时间】:2017-10-08 22:36:49 【问题描述】:

我正在尝试使用 proguard 混淆代码,因此我在发布构建类型中启用了 minify

buildTypes 
    debug 
        minifyEnabled false
    
    release 
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt')
    

但是当我生成“发布 apk”并安装它后,应用程序运行速度变慢(滞后)..为什么在启用 minify 时会发生这种情况? 这是我的依赖项:

dependencies 
    compile 'com.android.support:support-v4:25.3.1'
    compile 'com.android.support:recyclerview-v7:25.3.1'
    compile 'com.android.support:palette-v7:25.3.1'
    compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-2'
    compile 'com.jrummyapps:colorpicker:2.1.6'
    compile 'org.apache.commons:commons-lang3:3.4'
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:design:25.3.1'
    compile project(':library')

    testCompile 'junit:junit:4.12'
    androidTestCompile 'com.android.support.test:runner:0.5'
    androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
    androidTestCompile 'com.android.support:support-annotations:25.3.1'

这是我的proguard-android.txt

# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose

# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.

-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService

# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * 
    native <methods>;


# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View 
   void set*(***);
   *** get*();


# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity 
   public void *(android.view.View);


# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * 
    public static **[] values();
    public static ** valueOf(java.lang.String);


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


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


# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version.  We know about them, and they are safe.
-dontwarn android.support.**

# Understand the @Keep support annotation.
-keep class android.support.annotation.Keep

-keep @android.support.annotation.Keep class * *;

-keepclasseswithmembers class * 
    @android.support.annotation.Keep <methods>;


-keepclasseswithmembers class * 
    @android.support.annotation.Keep <fields>;


-keepclasseswithmembers class * 
    @android.support.annotation.Keep <init>(...);

我尝试添加:

-keep class com.mylibrary.**
-keep interface com.mylibrary.**
-keep enum com.mylibrary.**

我的库依赖:

dependencies 
    compile fileTree(include: ['*.jar'], dir: 'libs')
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', 
        exclude module: 'support-annotations'
    )
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support:palette-v7:25.3.1'
    testCompile 'junit:junit:4.12'
    compile 'com.google.code.gson:gson:2.8.0'
    compile 'org.jetbrains:annotations-java5:15.0'

【问题讨论】:

你是否打开了即时运行请关闭它删除项目中的构建文件夹再次构建它并告诉我我认为 progaurd 没有问题。 在调试模式下不会发生,只有在我签署apk(发行版)时才会发生 是的,您是否尝试禁用即时运行? @ReyanshMishra 试过了,但没有... 您能发布proguard-android.txt 文件吗?您可能混淆了不应该使用的库...您是否注意到在使用某个库时会出现延迟,或者只是一般情况下? 【参考方案1】:

虽然proguard-android.txt 中的 cmets 指定了一些原因,但我很惊讶地看到禁用某些优化的标志,因为默认自动生成的 proguard-android.txt 文件在创建新的 Android 项目时不包含此类标志。尝试删除以下行,看看是否有改进:

-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontoptimize
-dontpreverify

文件的其余部分似乎很好,虽然我没有检查所有正在使用的库,但我检查了几个并意识到您已经为它们添加了必要的例外。

如果没有解决,您必须确保正确添加正在使用的库的异常,并检查 proguard-android.txt 内的 library 模块,因为它在依赖项中被引用.

【讨论】:

还是一样...可能是库模块?但它有相同的保护规则 如果我在库模块上启用 minify 比我无法编译项目,因为它显示许多导入错误(包 com.mylibrary 不存在) 没错,这是因为 ProGaurd 混淆了他们的名字,从而导致了错误 那我该如何解决呢? 您可以使用systrace 之类的工具,或者只是简单地将logcat 与特定代码相关的日志来检查导致特定页面滞后的确切原因。【参考方案2】:

ProGuard 不会导致应用程序在运行时出现延迟。这可能是由于您的库之一包含在 gradle 文件中。

【讨论】:

【参考方案3】:

我强烈建议您使用 Android Studio Profiler 查看应用的行为方式和行为方式。我的意思是内存、CPU、网络等。 保存结果以进行比较,然后尝试仅使用 proguard 更改的相同应用程序版本。 性能影响不太可能来自proguard。 如果可能,请在此处传递结果和您的观察结果以进行进一步分析。 另请注意,构建类型也有所不同,您在调试/发布风格中是否有不同的代码?

【讨论】:

【参考方案4】:

Java 在第一次退出时总是运行缓慢。因为它必须被加载和解释。再次运行测试。看看这个问题。

Java program runs slower when code that is never executed is commented out

【讨论】:

我已经尝试重启应用程序很多次了。这并没有帮助,因为如果用户第一次运行应用程序并得到延迟,它就会消失 好吧,把我记下来,它对其他用途更明显。

以上是关于ProGuard 导致应用滞后的主要内容,如果未能解决你的问题,请参考以下文章

如何修复因 ProGuard/R8 导致的崩溃?

proguard 导致谷歌播放服务的 ActivityRecognitionResult getMostProbableActivity 崩溃

Android proguard 混淆代码实际上不应该导致 NullPointerException

Proguard导致崩溃

Proguard导致杰克逊错误

Proguard 混淆导致 java.lang.IllegalArgumentException:类声明多个名为“a”的 JSON 字段