工程地址为Mess git。
使用方式如下:
dependencies {
...
// 引用该库
classpath 'me.ele:mess-plugin:1.1.5'
}
apply plugin: 'com.android.library'
// 或 apply plugin: 'com.android.application'
apply plugin: 'me.ele.mess'
// 由于不能兼容 Butter Knife,所以需要加入如下
mess {
ignoreProguard 'com.jakewharton:butterknife'
}
注: 有另外一个库,做了兼容,地址为(ButterMess)[https://github.com/peacepassion/ButterMess]
由于替换写在xml里面的自定义View,而 appt2 编译过程产生的不再是 xml文件,而是flat文件,所以需要在 gradle.properties 文件添加如下代码:
android.enableAapt2=false
作者编译改工程的时候,使用的 gradle 是 2.* 或 3.* ,所以 AndroidManifest.xml 目录在 RewriteComponentTask 中有如下定义:
String realPath = "${project.buildDir.absolutePath}/intermediates/manifests/full/${getSubResPath()}/AndroidManifest.xml"
而 gradle 4.* 目录将变为
// debug 为
String realPath = "${project.buildDir.absolutePath}/intermediates/merged_manifests/${getSubResPath()}/processDebugManifest/merged/AndroidManifest.xml"
// release为
String realPath = "${project.buildDir.absolutePath}/intermediates/merged_manifests/${getSubResPath()}/processReleaseManifest/merged/AndroidManifest.xml"
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Service
-keep public class * extends android.view.View
# 全局:保留所有继承自View的子类名称
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public (android.content.Context, android.util.AttributeSet, int);
}
如果是,请去除。
2)部分 Activity 混淆成功了,部分没有成功,切应用启动之后,报了 ClassNotFound 的crash,需要在 proguard-rules.pro 或 proguard.cfg 文件中加入,如下
-dontshrink
Mess 的 大致原理可以分为两部分:
1)在 processResourcesTask 之后,删除如下路径的文件。
build/generated/intermediates/proguard-rules/debug[或]release/aapt_rules.txt
使得 proguard 能将View和Activity等进行混淆。
2)在transformClassesAndResourcesWithProguardFor* 之后,根据生成的 mapping.txt 文件,对 AndroidMenifest.xml 文件以及其他 res 文件中的相关字段进行替换。
这里有一个重大的bug: 如:
// mapping.txt 有如下字段
d.c -> someWhat
// 然后
xmlns:android="http://schemas.android.com/apk/res/android"
被替换为
// xmlns:android="http://schemas.androi[d.c]om/apk/res/android"
xmlns:android="http://schemas.androisomewhatom/apk/res/android"
然后就各种布局bug了
其实 aapt_rules.txt 里面如下定义:
# view res/layout/layout_1.xml #generated:2
# view res/layout/layout_2.xml #generated:9
-keep class com.lxb.sample.MyView { (...); }
由上面可以看出,其实哪个xml里面有那些 View 等,都已经比较明确,所以只需要替换相应的 xml 里面的 相应的 Class 字段就可以,避免出现(三)中的异常。
原工程中遍历了所有的资源文件,遍历所有的mapping的内容,进行替换处理,就会出现(三)中的异常,根据(四)的建议,就可以进行改进处理。
原工程不支持 aapt2 是因为,aapt2将资源文件压缩为.flat文件,无法直接通过替换字符串的方式进行替换。
那么我们为什么一定要揪住.flat文件不放呢?直接修改源文件,然后执行 aapt2 替换之前的 .flat 不久行了吗?
改进的项目地址为:https://github.com/linxuebin1990/Mess
和(一)中所说无差,只要自己进行一次编包处理将如下文件拷贝到主工程目录下。
MessProjuecPath/buildSrc/build/libs/buildSrc.jar
然后,
dependencies {
...
// 引用该库,将(一)中的 classpath 'me.ele:mess-plugin:1.1.5' 改为如下方式
classpath files('./buildSrc.jar')
}
再之后,将aapt2文件,也同样拷贝到主工程目录下,就可以。
其他参考前面的配置就可以。