本篇文章主要介绍了Android混淆的最佳实践,包括混淆配置、自定义混淆规则等。希望能够帮助大家解决在混淆过程中遇到的问题,避免走回头路。
1. 混淆配置
在release模式下,需要设置minifyEnabled为true,shrinkResources为true,以及proguardFiles和signingConfigs。具体配置如下:
```java
android{
buildTypes {
release {
buildConfigField "boolean", "LOG_DEBUG", "false" //不显示log
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.config
}
}
}
```
2. 自定义混淆规则
自定义混淆方案适用于大部分的项目。可以通过以下方式进行配置:
```java
android{
buildTypes {
release {
buildConfigField "boolean", "LOG_DEBUG", "false" //不显示log
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
signingConfig signingConfigs.config
}
}
}
```
重构后的内容如下:
```
buildTypes {
debug {
minifyEnabled false // 混淆
zipAlignEnabled true // Zipalign优化
shrinkResources true // 移除无用的resource文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 加载默认混淆配置文件
signingConfig signingConfigs.debug // 签名
}
release {
minifyEnabled true // 混淆
zipAlignEnabled true // Zipalign优化
shrinkResources true // 移除无用的resource文件
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 加载默认混淆配置文件
signingConfig signingConfigs.release // 签名
}
}
```
2. 混淆规则
混淆会用无意义的短变量去重命名类、变量、方法,但是对于外部的一些引用是通过名字找到对应的方法和类。混淆过后通过原来的名字去找混淆后的名字,是找不到对应方法和类,就会出异常报错。所以有些情况是不能进行混淆的。
自定义控件不进行混淆
枚举类不被混淆
反射类不进行混淆
实体类不被混淆
JS调用的Java方法
四大组件不进行混淆
JNI中调用类不进行混淆
Layout布局使用的View构造函数、android:onClick等
Parcelable 的子类和 Creator 静态成员变量不混淆
第三方开源库或者引用其他第三方的SDK包不进行混淆
3. 混淆模板
1)基本指令
```
# 设置混淆的压缩比率 0 ~ 7 -optimizationpasses 5
# 混淆时不使用大小写混合,混淆后的类名为小写 -dontusemixedcaseclassnames
# 指定不去忽略非公共库的类 -dontskipnonpubliclibraryclasses
# 指定不去忽略非公共库的成员 -dontskipnonpubliclibraryclassmembers
# 混淆时不做预校验 -dontpreverify # 混淆时不记录日志 -verbose # 忽略警告 -ignorewarning # 代码优化 -dontshrink # 不优化输入的类文件 -dontoptimize # 保留注解不混淆 -keepattributes *Annotation*,InnerClasses
# 避免混淆泛型 -keepattributes Signature # 保留代码行号,方便异常信息的追踪 -keepattributes SourceFile,LineNumberTable
# 混淆采用的算法 -optimizations !code/simplification/cast,!field/*,!class/merging/*
# dump.txt文件列出apk包内所有class的内部结构 -dump class_files.txt # seeds.txt文件列出未混淆的类和成员 -printseeds seeds.txt # usage.txt文件列出从apk中删除的代码 -printusage unused.txt # mapping.txt文件列出混淆前后的映射 -printmapping mapping.txt
```
2)不需混淆的Android类
请根据以下要求重构内容,并保持段落结构:
1. 保留以下类的公共子类:
```java
- keep public class * extends android.app.Fragment;
- 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.preference.Preference;
- keep public class * extends android.content.ContentProvider;
- keep public class * extends android.support.v4.**;
- keep public class * extends android.support.annotation.**;
- keep public class * extends android.support.v7.**;
- keep public class * extends android.app.backup.BackupAgentHelper;
- keep public class * extends android.preference.Preference;
- keep public class * extends android.view.View;
```
2. 保留以下类及其公共子类:
```java
- keep public class com.android.vending.licensing.ILicensingService;
```
3. 保留以下类及其公共子类的所有包:
```java
- keep class android.support.** {*;}
```
以下是重构后的代码:
```
-dontwarn android.support.v4.** -keep class android.support.v4.app.** { *; } -keep interface android.support.v4.app.** { *; } -keep class android.support.v4.** { *; }
-dontwarn android.support.v7.** -keep class android.support.v7.internal.** { *; } -keep interface android.support.v7.internal.** { *; } -keep class android.support.v7.** { *; }
-dontwarn android.support.design.** -keep class android.support.design.** { *; } -keep interface android.support.design.** { *; } -keep public class android.support.design.R$* { *; }
-keep public class * extends android.view.View{
*** get*(); void set*(***);
public <init>(android.content.Context);
public <init>(android.content.Context, android.util.AttributeSet);
public <init>(android.content.Context, android.util.AttributeSet, int); }
```
请根据提供的内容完成内容重构,并保持段落结构:
以下是一些Android开发过程中需要注意的规则和建议,以避免混淆问题:
1. 避免方法名冲突:在编写代码时,尽量避免使用与系统类库或第三方库中已有的方法名相同的方法名,以免引起混淆。同时,对于需要使用的系统类库或第三方库中的类,可以在方法内部添加注解@hide,表示该类仅供内部使用,不应该被外部调用。
2. 使用正确的访问修饰符:在定义变量、方法和内部类时,应该根据其作用范围选择合适的访问修饰符(public、private、protected等)。例如,如果一个变量只在当前类中使用,那么应该将其定义为private;如果需要在其他类中访问该变量,则可以将其定义为public。
3. 避免资源混淆:在布局文件中,可以通过指定不同的resource-id来避免资源混淆。例如,可以将按钮的background设置为`@drawable/button_bg`,这样就可以避免与系统自带的按钮样式混淆。
4. 保留R$*.class文件:为了避免布局文件中的点击事件与其他控件的点击事件混淆,可以使用以下规则保留R$*.class文件:
```java
-keep class **.R$* {*;}
```
5. 避免回调函数混淆:在实现接口时,如果使用了原生方法作为回调函数,应该使用native关键字进行标记,并在方法内部添加相应的注解@hide。例如:
```java
@hide
public void onClick(View v) {
nativeOnClick(v);
}
```
6. 避免枚举类混淆:如果需要自定义一个枚举类,应该注意不要将enum后面的Item作为枚举实例的属性名。可以使用以下规则避免混淆:
```java
-keepenumclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
```
7. 保留本地方法:如果在代码中使用了本地方法(native method),应该使用native关键字进行标记,并在方法内部添加相应的注解@hide。例如:
```java
@hide
public native void nativeMethod();
```
8. 避免Parcelable接口混淆:如果需要自定义一个实现了Parcelable接口的类,应该注意不要将public static final android.os.Parcelable$Creator *;这行代码中的*替换成实际的成员变量或方法名。可以使用以下规则避免混淆:
```java
-keep class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
```
5)WebView混淆配置```
-keepclassmembers class fqcn.of.javascript.interface.for.webview { public *; }
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.WebView, java.lang.String, android.graphics.Bitmap);
public boolean *(android.webkit.WebView, java.lang.String);
}
-keepclassmembers class * extends android.webkit.webViewClient {
public void *(android.webkit.webView, jav.lang.String);
}
```
16)ButterKnife混淆配置
7)OkHttp3混淆配置```
-dontwarn com.squareup.okhttp3.**
-keep class com.squareup.okhttp3.** { *;}
-dontwarn okio.**
```
18)Retrofit2混淆配置
```
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
```
19)RxJava、RxAndroid混淆配置
```
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* { long producerIndex; long consumerIndex; }
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef { rx.internal.util.atomic.LinkedQueueNode producerNode; }
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef { rx.internal.util.atomic.LinkedQueueNode consumerNode; }
```
20)Glide混淆配置(Glide 3)
```
Glide 3的混淆配置与Glide 2略有不同,需要将以下内容添加到proguard-rules.pro文件中:
```
-keep class com.bumptech.glide.load.resource.bitmap.ImageHeaderParser {}
-keep class com.bumptech.glide.load.resource.bitmap.RoundedCorners {}
-keep class com.bumptech.glide.load.resource.gif.GifDrawable {}
-keep class com.bumptech.glide.load.resource.gifpack.GifPackDrawable {}
-keep class com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions {}
-keep class com.bumptech.glide.request.RequestListener {}
-keep class com.bumptech.glide.request.target.TargetSize {}
-keep class com.bumptech.glide.request.transition.Transition {}
```
Glide 4混淆配置:```java
-keep public class * implements com.bumptech.glide.module.GlideModule {
-keep public enum com.bumptech.glide.load.resource.bitmap.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
}
```
21)Picasso混淆配置:
```java
-keep class com.parse.*{ *; } -dontwarn com.parse.** -dontwarn com.squareup.picasso.** -keepclasseswithmembernames class * {
native <methods>;
}
```
22)Fresco混淆配置:
```java
-keep public class * implements com.facebook.drawee.backends.pipeline.Fresco;
-keep public interface * extends android.os.IInterface {
boolean isAssignableFrom(Class> arg0);
String getName();
int getFeatureId();
}
-dontwarn android.graphics.BitmapFactory -dontwarn android.support.annotation.NonNull
-keep class **com.facebook.drawee.backends.pipeline.** {*;}
-keepclassmembers class **com.facebook.drawee.backends.pipeline.** {*;}
```
为了保持接口的可用性,以便其他ProGuard规则可以使用,我们需要添加以下配置:
```java
# 保留我们的接口,以便其他ProGuard规则可以使用。请参阅http://sourceforge.net/p/proguard/bugs/466/ -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip -keep,allowobfuscation @interface com.facebook.soloader.DoNotOptimize
-keep @com.facebook.common.internal.DoNotStrip class * -keepclassmembers class * { @com.facebook.common.internal.DoNotStrip *; }
# 保留任何使用@DoNotStrip注解的方法/类
-keep @com.facebook.common.internal.DoNotStrip class * -keepclassmembers class * { @com.facebook.common.internal.DoNotStrip *; }
# 保留本地方法
-keepclassmembers class * { native <methods>; }
```
接下来,我们需要禁用Fastjson相关的警告:
```java
-dontwarn okio.**
-dontwarn com.squareup.okhttp.**
-dontwarn okhttp3.**
-dontwarn javax.annotation.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.facebook.infer.**
```
以下是Android应用的混淆配置,包括关键字认知、基本指令、通用配置(涵盖androidx和Kotlin)、实体类混淆以及第三方库的混淆设置。并提供了混淆配置的实例和下载链接。
- 通用配置:proguard-rules.pro(位于 ANDROID_SDK\tools\proguard 目录)
- Kotlin项目:kotlin-android.jar(位于 ANDROID_SDKtools\base\libs 目录)
- 第三方库:在第三方库的build.gradle文件中添加混淆规则
混淆配置如下:
1 百度地图混淆配置
```
-keep class com.baidu.** {*;}
-keep class vi.com.** {*;}
-dontwarn com.baidu.**
```
2. 高德地图混淆配置
```
-dontwarn com.amap.api.**
-dontwarn com.a.a.**
-dontwarn com.autonavi.**
-keep class com.amap.api.** {*;}
-keep class com.autonavi.** {*;}
-keep class com.a.a.** {*;}
```
3. Bugly混淆配置
```
-dontwarn com.tencent.bugly.**
-keep public class com.tencent.bugly.**{*;}
```
4. EventBus混淆配置(EventBus 2)
```
-keepclassmembers class ** { public void onEvent*(***); } # Only required if you use AsyncExecutor
-keepclassmembers class * extends de.greenrobot.event.util.ThrowableFailureEvent { <init>(java.lang.Throwable); }
```
5. EventBus混淆配置(EventBus 3)
以下是友盟分享混淆配置的一些规则,供您参考:
- 保留友盟分享SDK相关的类和成员不被混淆。
- 保留友盟分享SDK相关的包不被混淆。
- 保留友盟分享SDK相关的注解不被混淆。
- 保留友盟分享SDK相关的枚举类型不被混淆。
```java
-dontshrink -dontoptimize -dontwarn com.google.android.maps.** -dontwarn android.webkit.WebView -dontwarn com.umeng.** -dontwarn com.tencent.weibo.sdk.** -dontwarn com.facebook.** -keep public class javax.** -keep public class android.webkit.** -dontwarn android.support.v4.** -keep enum com.facebook.** -keepattributes Exceptions,InnerClasses,Signature -keepattributes *Annotation* -keepattributes SourceFile,LineNumberTable
-keep public interface com.facebook.** -keep public interface com.tencent.** -keep public interface com.umeng.socialize.** -keep public interface com.umeng.socialize.sensor.** -keep public interface com.umeng.scrshot.**
-keep public class com.umeng.socialize.* {*;}
-keep class com.facebook.** -keep class com.facebook.** { *; }
-keep class com.umeng.scrshot.**
-keep public class com.tencent.** {*;}
-keep class com.umeng.socialize.sensor.**
-keep class com.umeng.socialize.handler.**
-keep class com.umeng.socialize.handler.*
-keep class com.umeng.weixin.handler.**
-keep class com.umeng.weixin.handler.*
-keep class com.umeng.qq.handler.**
-keep class com.umeng.qq.handler.*
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-keep class com.tencent.open.TDialog$*
-keep class com.tencent.open.TDialog$* {*;}
-keep class com.tencent.open.PKDialog
-keep class com.tencent.open.PKDialog {*;}
-keep class com.tencent.open.PKDialog$*
-keep class com.tencent.open.PKDialog$* {*;}
-keep class com.umeng.socialize.impl.ImageImpl {*;}
-keep class com.sina.** {*;}
-dontwarn com.sina.**
-keep class com.alipay.share.sdk.** { *; }
-keepnames class * implements android
在友盟推送的混淆配置中,需要排除一些不需要混淆的包。以下是一个示例配置:
```
-dontwarn com.umeng.** -dontwarn com.taobao.** -dontwarn anet.channel.** -dontwarn anetwork.channel.** -dontwarn org.android.** -dontwarn org.apache.thrift.** -dontwarn com.xiaomi.** -dontwarn com.huawei.** -dontwarn com.meizu.**
-keepattributes *Annotation*
-keep class com.taobao.** {*;}
-keep class org.android.** {*;}
-keep class anet.channel.** {*;}
-keep class com.umeng.** {*;}
-keep class com.xiaomi.** {*;}
-keep class com.huawei.** {*;}
-keep class com.meizu.** {*;}
-keep class org.apache.thrift.** {*;}
-keep class com.alibaba.sdk.android.**{*;}
-keep class com.ut.**{*;}
-keep class com.ta.**{*;}
-keep public class **.R$*{ public static final int *; }
```
```makefile
#指定压缩级别 -optimizationpasses 5
#不跳过非公共的库的类成员 -dontskipnonpubliclibraryclassmembers
#混淆时采用的算法 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#把混淆类中的方法名也混淆了 -useuniqueclassmembernames
#优化时允许访问并修改有修饰符的类和类的成员 -allowaccessmodification
#将文件来源重命名为“SourceFile”字符串 -renamesourcefileattribute SourceFile
#保留行号 -keepattributes SourceFile,LineNumberTable
#保持泛型 -keepattributes Signature
#保持所有实现 Serializable 接口的类成员 -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();
}
#Fragment不需要在AndroidManifest.xml中注册,需要额外保护下
-keep public class * extends android.support.v4.app.Fragment
-keep public class * extends android.app.Fragment
#保持测试相关的代码
-dontnote junit.framework.**
-dontnote junit.runner.**
-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**
```
您好!ProGuard是一个Android应用程序的压缩、优化和混淆工具。它可以移除无用代码,提高运行速度,增加安全性。在使用ProGuard时,需要添加一些混淆规则来保护您的代码不被轻易反编译。以下是一些常用的混淆规则:
- keep public class **.*Model*.** {*;}
- JNI中调用的类
- JavaScript
- android:onClick
除此之外,每个项目都需要根据自身需求添加一些第三方库所需的混淆规则。例如:
- 第三方库所需的混淆规则。正规的第三方库一般都会在接入文档中写好所需混淆规则,使用时注意添加。
- /build/outputs/mapping/release/dump.txt
- /tools/proguard/proguardgui.batproguardgui.sh
这些文件提供了关于APK文件中所有类的内部结构、对照表、未被混淆的类和成员以及被移除的代码等信息。您可以通过这些文件检查混淆结果。
在Android开发中,为了保护自己的应用不被轻易逆向分析,开发者通常会使用代码混淆、优化和压缩等技术。这些技术可以帮助开发者隐藏代码信息,降低反编译的难度,提高应用的安全性和稳定性。下面我们详细介绍一下如何使用proguard进行代码混淆、优化和压缩。
1. 配置混淆规则
在项目根目录下创建一个名为`proguard-rules.pro`的文件,用于存放自定义的混淆规则。在这个文件中,我们可以定义哪些类、方法、字段等需要被混淆,以及如何混淆。例如:
```
# 保持所有的类名不被混淆
-keep class * {
public protected *;
}
# 保持所有公共方法不被混淆
-keepclassmembers class * {
public static **(...);
}
```
2. 在`build.gradle`文件中启用混淆功能
在项目的`build.gradle`文件中,我们需要设置一些参数来启用混淆功能。例如:
```groovy
android {
...
buildTypes {
release {
minifyEnabled true // 启用代码压缩和混淆
shrinkResources true // 启用资源压缩
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' // 使用默认的混淆规则和自定义的混淆规则
}
}
}
```
3. 生成混淆后的APK
在完成上述配置后,我们可以使用Gradle命令行工具或者Android Studio的构建功能来生成混淆后的APK。例如:
```bash
gradle assembleRelease // 或者在Android Studio中点击Build -> Build Bundle(s) / APK(s) -> Build APK(s)
```
4. 查看混淆效果
生成混淆后的APK后,我们可以使用APK分析工具(如dex2jar、JD-GUI等)来查看混淆前后的APK对比,以验证混淆是否生效。
需要特别介绍的是与保持相关元素不参与混淆的规则相关的几种命令:
1. -keep:防止类和成员被移除或者被重命名。
2. -keepnames:防止类和成员被重命名。
3. -keepclassmembers:防止成员被移除或者被重命名。
4. -keepnames:防止成员被重命名。
5. -keepclasseswithmembers:防止拥有该成员的类和成员被移除或者被重命名。
6. -keepclasseswithmembernames:防止拥有该成员的类和成员被重命名。
保持元素不参与混淆的规则格式如下:
```
[保持命令] [类] { [成员] }
```
其中,“类”代表类相关的限定条件,它将最终定位到某些符合该限定条件的类。它的内容可以使用以下选项:
- 具体的类
- 访问修饰符(public、protected、private)
- 通配符*,匹配任意长度字符,但不含包名分隔符(.)
- 通配符**,匹配任意长度字符,并且包含包名分隔符(.)
- extends,即可以指定类的基类
- implement,匹配实现了某接口的类
- $$,内部类
“成员”代表类成员相关的限定条件,它将最终定位到某些符合该限定条件的类成员。它的内容可以使用以下选项:
- <init> 匹配所有构造器
- <fields> 匹配所有域
- <methods> 匹配所有方法
- 通配符*,匹配任意长度字符,但不含包名分隔符(.)
- 通配符**,匹配任意长度字符,并且包含包名分隔符(.)
- 通配符***,匹配任意参数类型
- ...,匹配任意长度的任意类型参数。比如void test(...)就能匹配任意 void test(String a) 或者是 void test(int a, String b) 这些方法。
- 访问修饰符(public、protected、private)
举个例子,假如需要将com.biaobiao.test包下所有继承Activity的public类及其构造函数都保持住,可以这样写:
```java
-keep public class com.biaobiao.test.** extends android.app.Activity {
```
请根据提供的内容完成内容重构,并保持段落结构:
```
-keep class com.biaobiao.test.** { *; }
不混淆某个类的子类
-keep public class * extends com.biaobiao.example.Test { *; }
不混淆所有类名中包含了“model”的类及其成员
-keep public class * extends com.biaobiao.example.Test { *; }
不混淆某个接口的实现
-keep class * implements com.biaobiao.example.TestInterface { *; }
不混淆某个类的构造方法
-keepclassmembers class com.biaobiao.example.Test { public <init>(); }
不混淆某个类的特定的方法
-keepclassmembers class com.biaobiao.example.Test { public void test(java.lang.String); }
不混淆某个类的内部类
-keep class com.biaobiao.example.Test$* { *; }
自定义资源保持规则
1. keep.xml
shrinkResources trueres/raw/keep.xml
通过一些属性的设置可以实现定义资源保持的需求,可配置的属性有:
keepdiscardshrinkModeResources.getIdentifier()Resources.getIdentifier()
String name = String.format("img_%1d", angle + 1); res = getResources().getIdentifier(name, "drawable", getPackageName());
tools:shrinkModestrict
以上就是自定义资源保持规则相关的配置,举个例子:
```
以下是重构后的代码:
```xml
...
...
android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> ...
android:id="@+id/unused2"> ...
```
请确认以下代码是否符合您的要求:
```java
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-keepattributes Signature
-keepattributes *Annotation*,InnerClasses
-optimizations !code/simplification/arithmetic,!code/simplification/cast,!field/*,!class/merging/*
-dontwarn android.support.**
-dontwarn android.support.**
-keep public class * extends android.support.v4.**
-keep public class * extends android.support.v7.**
-keep public class * extends android.support.annotation.**
-keep class **.R$* {*;}
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Appliction
-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 com.android.vending.licensing.ILicensingService
-keepclassmembers class * extends android.app.Activity{ public void *(android.view.View); }
-keepclassmembers class * { void *(**On*Event); void *(**On*Listener); }
-keeplocalnativemethodsclass members interface * { native <methods>; }
-keepclasseswithmembernames class * { native <methods>; }
-keepenums enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-keepclassmembers enum * { public static **[] values(); public static ** valueOf(java.lang.String); }
-keepclassmembers class * implements android.os.Parcelable { public static final android.os.Parcelable$Creator *; }
-keepclassmembers class * implements java.io.Serializable { static final long serialVersionUID; private static final java.io.ObjectStreamField[] serialPersistentFields; ... }
#assume no side effects:删除android.util.Log输出的日志
-assumenosideeffects class android.util.Log { ... }
#保留Keep注解的类名和方法
-keep,allowobfuscation @interface android.support.annotation.Keep
-keep @android.support.annotation.Keep class *
#3D地图 V5.0.0之前:忽略com.amap.api.**和com.autonavi.**包下的警告信息
#3D地图 V5.0.0之后:忽略com.amap.api.maps.**、com.autonavi.**和com.autonavi.amap.mapcore。*包下的警告信息
#定位相关类不被混淆的保留规则与上述类似,只是类名有所变化。具体可参考注释中的说明。
#搜索相关类不被混淆的保留规则与上述类似,只是类名有所变化。具体可参考注释中的说明。
#2D地图相关类不被混淆的保留规则与上述类似,只是类名有所变化。具体可参考注释中的说明。
#导航相关类不被混淆的保留规则与上述类似,只是类名有所变化。具体可参考注释中的说明。
```
对不起,但是您没有提供具体的文章或内容供我参考和重构。如果您能提供更多详细信息,如原文、主题或关键点等,我会很高兴帮助您。