Class 升级到 Android Gradle 插件 3.4.0 后不再混淆
Class no longer obfuscated after upgrading to Android Gradle plugin 3.4.0
升级到AndroidGradle插件3.4.0后,基础class不再混淆
以下基本步骤可以重现问题:
- 在 Android Studio 中创建一个新的空项目
- 在
app/build.gradle
中将 minifyEnabled
更改为 true
创建以下class,ProguardTestClass.java
:
public class ProguardTestClass {
public interface ProguardTestInnerInterface {
void proguardTestCallback(String message);
}
public static void proguardTestMethod(String input, ProguardTestInnerInterface impl) {
impl.proguardTestCallback("proguardTestMethod received input=[" + input + "]");
}
}
参考MainActivity.java
中的class:
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ProguardTestClass.proguardTestMethod("MainActivity's ProguardTestClass", new ProguardTestClass.ProguardTestInnerInterface() {
@Override
public void proguardTestCallback(String message) {
Log.d(TAG, "Proguard test: " + message);
}
});
}
}
确认它在build.gradle
中使用AndroidGradle插件3.4.0
- 确认它在
gradle/wrapper/gradle-wrapper.properties
中使用 gradle-5.1.1
- 在“终端”选项卡中打开一个终端window
- 运行
./gradlew clean build
- 运行
find . -name mapping.txt | xargs grep "ProguardTestClass -> "
预期输出:
com.example.proguardgradleplugin340.ProguardTestClass -> com.example.proguardgradleplugin340.a:
实际输出:
app/build/outputs/mapping/release/mapping.txt
没有提到 ProguardTestClass
.
的任何重命名
要查看之前的 Android Gradle 插件版本是否可以产生预期的输出,请重复上述步骤,但指向 Android Gradle 插件的早期版本和 Gradle:
- 在
build.gradle
中更改为AndroidGradle插件3.3.2
- 在
gradle/wrapper/gradle-wrapper.properties
中更改为gradle-4.10.1
我试图通过查看其他 diagnostic files that we used to get from Proguard 来进行调查,但它们不再输出(至少默认情况下不会):
find . -name seeds.txt
find . -name usage.txt
我还查看了 Android Gradle 插件 3.4.0 发行说明,发现它取代了 Proguard,转而支持一项 "integrates desugaring, shrinking, obfuscating, optimizing, and dexing all in one step".
的新技术
尝试设置 useProguard false
让插件使用 R8 而不是 ProGuard 来压缩和混淆您应用的代码和资源。例如。
android {
...
buildTypes {
debug {
minifyEnabled true
useProguard false
}
release {
minifyEnabled true
useProguard false
}
}
}
或者,如果您想坚持使用 ProGuard,您应该从 gradle.properties
禁用 R8,如下所示:
# Disables R8 for Android Library modules only.
android.enableR8.libraries = false
# Disables R8 for all modules.
android.enableR8 = false
并且记得设置useProguard true
。
编辑#1
在此处查看如何将 Proguard 迁移到 R8:Android/java: Transition / Migration from ProGuard to R8?
@shizhen 的解决方案是我接受的问题解决方案。但我想记录一个替代方案,以防其他人遇到这个问题。
我能够通过实际实例化 class 让 R8 混淆 class。请注意我的 ProguardTestClass
原始代码如何不包含构造函数,并且我以相当静态的方式使用它。但是当我添加一个构造函数并从 MainActivity.java
实例化它时,我猜这给了 R8 一个混淆它的理由。
修改 ProguardTestClass
使 R8 执行混淆:
public class ProguardTestClass {
//
// NEW CODE: BEGIN
//
private int avar;
public ProguardTestClass(int avar) {
this.avar = avar;
}
public int incrementValue() {
return ++avar;
}
//
// NEW CODE: END
//
public interface ProguardTestInnerInterface {
void proguardTestCallback(String message);
}
public static void proguardTestMethod(String input, ProguardTestInnerInterface impl) {
impl.proguardTestCallback("proguardTestMethod received input=[" + input + "]");
}
}
然后在 MainActivity.java
我在 onCreate()
上实例化并调用了 ProguardTestClass
:
proguardTestClass = new ProguardTestClass(3);
Log.d(TAG, "Proguard test: " + proguardTestClass.incrementValue());
升级到AndroidGradle插件3.4.0后,基础class不再混淆
以下基本步骤可以重现问题:
- 在 Android Studio 中创建一个新的空项目
- 在
app/build.gradle
中将minifyEnabled
更改为true
创建以下class,
ProguardTestClass.java
:public class ProguardTestClass { public interface ProguardTestInnerInterface { void proguardTestCallback(String message); } public static void proguardTestMethod(String input, ProguardTestInnerInterface impl) { impl.proguardTestCallback("proguardTestMethod received input=[" + input + "]"); } }
参考
MainActivity.java
中的class:public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ProguardTestClass.proguardTestMethod("MainActivity's ProguardTestClass", new ProguardTestClass.ProguardTestInnerInterface() { @Override public void proguardTestCallback(String message) { Log.d(TAG, "Proguard test: " + message); } }); } }
确认它在
build.gradle
中使用AndroidGradle插件3.4.0
- 确认它在
gradle/wrapper/gradle-wrapper.properties
中使用 - 在“终端”选项卡中打开一个终端window
- 运行
./gradlew clean build
- 运行
find . -name mapping.txt | xargs grep "ProguardTestClass -> "
gradle-5.1.1
预期输出:
com.example.proguardgradleplugin340.ProguardTestClass -> com.example.proguardgradleplugin340.a:
实际输出:
app/build/outputs/mapping/release/mapping.txt
没有提到 ProguardTestClass
.
要查看之前的 Android Gradle 插件版本是否可以产生预期的输出,请重复上述步骤,但指向 Android Gradle 插件的早期版本和 Gradle:
- 在
build.gradle
中更改为AndroidGradle插件3.3.2
- 在
gradle/wrapper/gradle-wrapper.properties
中更改为
gradle-4.10.1
我试图通过查看其他 diagnostic files that we used to get from Proguard 来进行调查,但它们不再输出(至少默认情况下不会):
find . -name seeds.txt
find . -name usage.txt
我还查看了 Android Gradle 插件 3.4.0 发行说明,发现它取代了 Proguard,转而支持一项 "integrates desugaring, shrinking, obfuscating, optimizing, and dexing all in one step".
的新技术尝试设置 useProguard false
让插件使用 R8 而不是 ProGuard 来压缩和混淆您应用的代码和资源。例如。
android {
...
buildTypes {
debug {
minifyEnabled true
useProguard false
}
release {
minifyEnabled true
useProguard false
}
}
}
或者,如果您想坚持使用 ProGuard,您应该从 gradle.properties
禁用 R8,如下所示:
# Disables R8 for Android Library modules only.
android.enableR8.libraries = false
# Disables R8 for all modules.
android.enableR8 = false
并且记得设置useProguard true
。
编辑#1
在此处查看如何将 Proguard 迁移到 R8:Android/java: Transition / Migration from ProGuard to R8?
@shizhen 的解决方案是我接受的问题解决方案。但我想记录一个替代方案,以防其他人遇到这个问题。
我能够通过实际实例化 class 让 R8 混淆 class。请注意我的 ProguardTestClass
原始代码如何不包含构造函数,并且我以相当静态的方式使用它。但是当我添加一个构造函数并从 MainActivity.java
实例化它时,我猜这给了 R8 一个混淆它的理由。
修改 ProguardTestClass
使 R8 执行混淆:
public class ProguardTestClass {
//
// NEW CODE: BEGIN
//
private int avar;
public ProguardTestClass(int avar) {
this.avar = avar;
}
public int incrementValue() {
return ++avar;
}
//
// NEW CODE: END
//
public interface ProguardTestInnerInterface {
void proguardTestCallback(String message);
}
public static void proguardTestMethod(String input, ProguardTestInnerInterface impl) {
impl.proguardTestCallback("proguardTestMethod received input=[" + input + "]");
}
}
然后在 MainActivity.java
我在 onCreate()
上实例化并调用了 ProguardTestClass
:
proguardTestClass = new ProguardTestClass(3);
Log.d(TAG, "Proguard test: " + proguardTestClass.incrementValue());