美文网首页
在 Android 中掌握 ProGuard

在 Android 中掌握 ProGuard

作者: Darren老师 | 来源:发表于2022-07-07 11:18 被阅读0次

    前言

    在构建 Android 应用程序时,我们可能在项目中使用了 ProGuard。在这篇文章中,我们将了解所有功能以及如何在 Android 中有效地使用 ProGuard。

    因此,让我们将其分解为以下几点:

    • 什么是 ProGuard?
    • 它对我们的应用有什么帮助?
    • 如何在我们的项目中使用它?
    • 需要注意的重要事项。

    什么是 ProGuard?

    ProGuard 是 Android 中的免费 java 工具,它可以帮助我们执行以下操作,

    • 缩小(缩小)代码:删除项目中未使用的代码。
    • 混淆代码:重命名类、字段等的名称。
    • 优化代码:做内联函数之类的事情。

    简而言之,ProGuard 对我们的项目产生了以下影响,

    • 它减小了应用程序的大小。
    • 它删除了导致 Android 应用程序的 64K 方法计数限制的未使用类和方法。
    • 它通过混淆代码使应用程序难以进行逆向工程。

    它对我们的应用程序有什么用处?

    在 Android 中,proguard 对于制作可用于生产的应用程序非常有用。它可以帮助我们减少代码并使应用程序更快。默认情况下,Proguard 在 Android Studio 中是开箱即用的,它在很多方面都有帮助,下面提到的很少,

    • 它混淆了代码,这意味着它将名称更改为一些较小的名称,例如MainViewModel它可能会将名称更改为A。在混淆应用程序之后,您的应用程序的逆向工程现在成为一项艰巨的任务。
    • 它缩小了资源,即忽略了我们的类文件没有调用的资源,没有在我们的android应用程序中使用,比如drawables中的图像等。这将大大减少应用程序的大小。您应该始终缩小您的应用程序以使其重量轻且速度快。

    如何在我们的项目中使用它?

    要在您的项目中启用 Proguard,请在应用程序的 build.gradle 添加,

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    
        }
    }
    

    在这里,我们minfyEnabled确实如此,它激活了从文件中获取的proguard,

    proguard-android.txt
    

    它在发布块下,这意味着它只会应用于我们生成的构建的发布。

    但有时当 proguard 删除太多代码时它可能太多了,它可能会破坏你的代码流。

    因此,配置代码我们必须添加一些自定义规则,以确保我们从混淆中删除代码集。我们可以通过在我们的 proguard 中编写自定义规则来解决这个问题,它会在生成构建时遵守。

    现在,让我们看看如何在 proguard 中编写自定义规则。

    1. 保存类文件
    假设我们有一个数据类,某些 API 需要它来执行它,但它会生成我们对类进行混淆的构建。例如,我们有一个用户数据类,

    data class User(val id: String = "")
    

    我们不想混淆生成构建的类,然后忽略它的混淆,我们使用@Keep注释并更新代码,例如,

    @Keep
    data class User(val id: String = "")
    

    此注释有助于在缩小时使用 proguard 来忽略该类。这将保留类及其成员函数,即使它们不被使用。

    我们还可以使用,

    -keep
    

    在生成构建时保留类的选项。使用-keep而不是@Keep,我们可以更好地控制要保留的内容和不保留的内容。

    但是,我们也可以通过使用@SerializedName(当使用 Gson 库时)来保留数据模型类中id字段的键,例如,

    data class User(@SerializedName("id")
                     val id: String = "")
    

    如果你注意到这里,我们没有使用@Keep。

    2. 为班级保留成员
    假设我们想在收缩时只保留类成员而不是类,然后我们使用,

    -keepclassmembers
    

    在 proguard 规则文件中。这将帮助我们忽略特定类的成员。

    考虑上面的 User 类,我们希望保留其中的所有公共方法。我们这样写规则,

    -keepclassmembers class com.mindorks.sample.User{
        public *;
    }
    

    在这里,类 User 保留所有具有公共修饰符的成员。

    3. 保留班级和成员的名字
    假设我们希望在代码中使用类和类成员的所有相同名称,即如果未使用该类,它将被 proguard 缩小但不会混淆,因为它已经被缩小了,所以没有需要混淆。

    要完成我们使用的上述任务,

    -keepnames
    

    它的实际使用看起来像,

    -keepnames class com.mindorks.sample.GlideModule
    

    在这里,如果 GlideModule 将保留其所有的类名称和成员函数。

    4.在Android中使用任何库
    在使用任何库时,我们可能希望为 proguard 编写一些自定义规则。库可能会在 logcat 中引发警告,或者他们甚至可能没有自己的 proguard 规则!

    为了解决这个问题,我们需要在应用程序端添加自定义规则。例如,如果我们开始从任何库中收到警告,那么我们添加,

    -dontwarn com.somelibrary.annotations.*
    

    在我们的 proguard 规则中,然后我们不会在日志中看到任何警告。

    要为库编写自定义规则,您可以像为自己的类编写任何其他规则一样编写它。

    5. 只混淆你的代码
    考虑一个非常罕见的用例,您只想混淆代码而不压缩任何资源。这是一个非常罕见的用例,但可能对一些小型库有用,然后我们编写如下标志,

    -dontshrink
    -dontoptimize
    

    这将帮助我们不缩小和优化代码而只是混淆。

    6. 维护注解
    在构建应用程序时,ProGuard 会删除所有注释,它可能仍然适用于您项目中的某些代码集。但是假设我们需要不删除注释,那么我们可以选择,

    -keepattributes *Annotation*
    

    在这里,它将所有注释的属性保留在您的应用程序中。它默认出现在我们的规则中。

    7.优化
    在 ProGuard 中编写了这么多规则之后,我们可能需要为我们的应用程序提供额外的优化层。首先,我们更新build.gradle文件,例如,

    android {
      buildTypes {
        release {
          proguardFiles getDefaultProguardFile('proguard-android-optimize.txt')
        }
      }
    }
    

    现在,一般来说,我们不使用此选项,但这里的用例是我们必须执行额外级别的优化。

    为了增加优化的周期数,例如我们想检查优化是否正确完成,如果没有完成,它将再次优化它直到我们使用一定次数,

    -optimizationpasses 5
    

    在这里,它将运行优化多达 5 次以使其更加优化。

    现在,考虑一个示例,与以前相比,我们希望更细粒度地优化最终类,我们使用,

    -optimizations class/marking/final
    

    在这里,最终的类将被优化最多 5 倍,或者如果优化已经完成,它甚至可能提前结束。

    现在,如果我们想优化我们现在使用的私有字段,

    -optimizations field/marking/private
    

    大多数情况下,优化是第一次完成。

    如果我们根本不想优化我们使用,

    -dontoptimize
    

    这就是我们如何以不同的方式使用 proguard 使我们的应用程序更安全和更轻便的工作方式。

    需要注意的重要事项:

    • 不要使用MainFragment.class.getSimpleName() 之类的东西作为片段标签。Proguard 可能会在混淆时为不同包中的两个不同片段分配相同的名称(A.class)。在这种情况下,两个片段将具有相同的 TAG。这将导致您的应用程序中的错误。
    • 保留 Proguard 的映射文件以追溯到原始代码。您可能必须将其上传到 PlayStore 控制台等不同的地方才能查看崩溃的原始堆栈跟踪。

    作者:Himanshu Singh
    链接:https://blog.mindorks.com/applying-proguard-in-an-android-application

    相关文章

      网友评论

          本文标题:在 Android 中掌握 ProGuard

          本文链接:https://www.haomeiwen.com/subject/puzubrtx.html