Android - Proguard 和改造 2?
Posted
技术标签:
【中文标题】Android - Proguard 和改造 2?【英文标题】:Android - Proguard and retrofit 2? 【发布时间】:2017-04-29 09:19:24 【问题描述】:我在我的项目中使用Proguard
,下面的代码在我的proguard-rules.pro
中:
# Retrofit
-keep class com.google.gson.** *;
-keep class com.google.inject.** *;
-keep class org.apache.http.** *;
-keep class org.apache.james.mime4j.** *;
-keep class javax.inject.** *;
-keep class javax.xml.stream.** *;
-keep class retrofit.** *;
-keep class com.google.appengine.** *;
-keepattributes *Annotation*
-keepattributes Signature
-dontwarn com.squareup.okhttp.*
-dontwarn rx.**
-dontwarn javax.xml.stream.**
-dontwarn com.google.appengine.**
-dontwarn java.nio.file.**
-dontwarn org.codehaus.**
-dontwarn retrofit2.**
-dontwarn org.codehaus.mojo.**
-keep class retrofit2.** *;
-keepattributes Exceptions
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
-keepattributes EnclosingMethod
-keepclasseswithmembers class *
@retrofit2.http.* <methods>;
-keepclasseswithmembers interface *
@retrofit2.* <methods>;
# Platform calls Class.forName on types which do not exist on android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on ios. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
# Add any classes the interact with gson
# the following line is for illustration purposes
-keep class com.example.asheq.zanis_postmans.ListAddressesActivity
-keep class com.example.asheq.zanis_postmans.ListOrderActivity
-keep class com.example.asheq.zanis_postmans.LoginActivity
-keep class com.example.asheq.zanis_postmans.SendReportsActivity
-keep class com.example.asheq.track.TrackLocationService
-keep class com.example.asheq.track.TrackLocationApplication
# Hide warnings about references to newer platforms in the library
-dontwarn android.support.v7.**
# don't process support library
-keep class android.support.v7.** *;
-keep interface android.support.v7.** *;
但是当我运行我的apk
时让我崩溃:
下面是我的毕业典礼:
apply plugin: 'com.android.application'
repositories
mavenCentral()
maven url "https://oss.sonatype.org/content/repositories/snapshots/"
android
compileSdkVersion 24
buildToolsVersion "24.0.2"
defaultConfig
applicationId "com.example.asheq.zanis_postmans"
minSdkVersion 16
targetSdkVersion 24
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
multiDexEnabled true
buildTypes
release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
dependencies
compile fileTree(include: ['*.jar'], dir: 'libs')
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2',
exclude group: 'com.android.support', module: 'support-annotations'
)
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support:multidex:1.0.1'
compile 'com.google.android.gms:play-services:9.6.1'
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'org.parceler:parceler-api:1.0.4'
compile 'com.google.android.gms:play-services:9.6.1'
compile 'com.google.android.gms:play-services-maps:9.6.1'
compile 'com.google.android.gms:play-services-places:9.6.1'
compile 'com.android.support:design:24.2.1'
compile 'com.google.android.gms:play-services-base:6.5.87'
compile 'com.google.android.gms:play-services-location:6.5.87'
compile 'com.google.maps.android:android-maps-utils:0.4.4'
//compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.google.code.gson:gson:2.6.1'
testCompile 'junit:junit:4.12'
compile 'com.android.support:cardview-v7:24.2.1'
compile 'com.android.support:recyclerview-v7:24.2.1'
compile 'com.michaelpardo:activeandroid:3.1.0-SNAPSHOT'
compile 'org.greenrobot:eventbus:3.0.0'
compile 'com.squareup.retrofit:retrofit:1.9.0'
compile 'com.weiwangcn.betterspinner:library-material:1.1.0'
//compile 'com.squareup.okhttp3:logging-interceptor:3.3.1'
这是我的TrackLocationApplication.class
:
public class TrackLocationApplication extends Application
private static final String KEY_REQUEST_DATA_NAME = "KEY_REQUEST_DATA_NAME";
private LocationRequestData locationRequestData;
private Location startLocation;
@Override
public void onCreate()
super.onCreate();
//checkAndSetDeviceId();
checkAndSetUserName();
if (!retrieveLocationRequestData())
//setLocationRequestData(LocationRequestData.FREQUENCY_MEDIUM);
setLocationRequestData(LocationRequestData.FREQUENCY_HIGH);
initializeDB();
private boolean retrieveLocationRequestData()
String name = PreferenceManager.getDefaultSharedPreferences(this).getString(KEY_REQUEST_DATA_NAME, null);
if (!TextUtils.isEmpty(name))
LocationRequestData data = LocationRequestData.valueOf(name);
if (data != null)
locationRequestData = data;
return true;
return false;
public void setLocationRequestData(LocationRequestData requestData)
locationRequestData = requestData;
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
preferences.edit().putString(KEY_REQUEST_DATA_NAME, requestData.name()).apply();
public LocationRequestData getLocationRequestData()
if (locationRequestData == null)
if (!retrieveLocationRequestData())
setLocationRequestData(LocationRequestData.FREQUENCY_HIGH);
return locationRequestData;
public Location getStartLocation()
return startLocation;
public void setStartLocation(Location startLocation)
this.startLocation = startLocation;
public LocationRequest createLocationRequest()
LocationRequest locationRequest = new LocationRequest();
locationRequest.setInterval(locationRequestData.getInterval());
locationRequest.setFastestInterval(locationRequestData.getFastestInterval());
locationRequest.setPriority(locationRequestData.getPriority());
locationRequest.setSmallestDisplacement(locationRequestData.getSmallestDisplacement());
return locationRequest;
// private void checkAndSetDeviceId()
// if (TextUtils.isEmpty(TrackLocationPreferencesManager.getDeviceId(this)))
// String deviceId = Utils.getUniqueDeviceId(this);
// TrackLocationPreferencesManager.setDeviceId(deviceId, this);
//
//
private void checkAndSetUserName()
if (TextUtils.isEmpty(TrackLocationPreferencesManager.getUserName(this)))
String userName = android.os.Build.MODEL;
TrackLocationPreferencesManager.setUserName(userName, this);
private void initializeDB()
Configuration.Builder configurationBuilder = new Configuration.Builder(this);
configurationBuilder.addModelClasses(LocationData.class);
ActiveAndroid.initialize(configurationBuilder.create());
@Override
protected void attachBaseContext(Context base)
super.attachBaseContext(base);
MultiDex.install(this);
【问题讨论】:
【参考方案1】:您需要保留模型,不要混淆它们。我看到你的模型有错误,sqlite 不能在你的模型上工作。应该是这样的:
-keep class package.to.yourmodels.** *;
【讨论】:
只有这个对我有用。我也试过这个***.com/questions/35506111/…。但只有肉山山解决方案对我有用 谢谢!我花了太多时间才发现这个问题,但现在一切正常【参考方案2】:2021解决方案
在您的数据类之前使用@keep
注释,以便保留它们。这消除了拥有单独的 Proguard 规则的需要。
表示在构建时缩小代码时不应删除带注释的元素。这通常用于仅通过反射访问的方法和类,因此编译器可能会认为代码未使用。
@Keep
data class Listing(
val id: String = "",
val name: String = ""
)
来源:https://developer.android.com/reference/kotlin/androidx/annotation/Keep
【讨论】:
如果我有 100 个数据类怎么办?一次循环遍历它们?这不合逻辑! 这有效(在请求和响应的主体对象上实现),但为什么它保留类的名称和字段名称?我不能让他们混淆吗?例如,我看到@SerializedName("country") val country: String?
的所有内容都相同。我至少不能混淆字段名称吗?
@blueware 确实可行,但正如您所说,这很烦人,而且我发现它不会改变任何东西的名称。这就是我发现的工作:***.com/a/66670232/878126【参考方案3】:
解决了我的问题:
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in C:\Users\asheq\AppData\Local\Android\Sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the javascript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview
# public *;
#
# Retrofit
-keep class com.google.gson.** *;
-keep public class com.google.gson.** public private protected *;
-keep class com.google.inject.** *;
-keep class org.apache.http.** *;
-keep class org.apache.james.mime4j.** *;
-keep class javax.inject.** *;
-keep class javax.xml.stream.** *;
-keep class retrofit.** *;
-keep class com.google.appengine.** *;
-keepattributes *Annotation*
-keepattributes Signature
-dontwarn com.squareup.okhttp.*
-dontwarn rx.**
-dontwarn javax.xml.stream.**
-dontwarn com.google.appengine.**
-dontwarn java.nio.file.**
-dontwarn org.codehaus.**
-dontwarn retrofit2.**
-dontwarn org.codehaus.mojo.**
-keep class retrofit2.** *;
-keepattributes Exceptions
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
-keepattributes EnclosingMethod
-keepclasseswithmembers class *
@retrofit2.http.* <methods>;
-keepclasseswithmembers interface *
@retrofit2.* <methods>;
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
# Add any classes the interact with gson
# the following line is for illustration purposes
-keep class com.example.asheq.zanis_postmans.ListAddressesActivity
-keep class com.example.asheq.zanis_postmans.ListOrderActivity
-keep class com.example.asheq.zanis_postmans.LoginActivity
-keep class com.example.asheq.zanis_postmans.SendReportsActivity
-keep class com.example.asheq.track.TrackLocationService
-keep class com.example.asheq.track.TrackLocationApplication
-keep class com.example.asheq.models.** *;
# Hide warnings about references to newer platforms in the library
-dontwarn android.support.v7.**
# don't process support library
-keep class android.support.v7.** *;
-keep interface android.support.v7.** *;
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.MapActivity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
# To support Enum type of class members
-keepclassmembers enum * *;
-keep class com.activeandroid.** *;
-keep class com.activeandroid.**.** *;
-keep class * extends com.activeandroid.Model
-keep class * extends com.activeandroid.serializer.TypeSerializer
-keepclassmembers class **
@org.greenrobot.eventbus.Subscribe <methods>;
-keep enum org.greenrobot.eventbus.ThreadMode *;
# Only required if you use AsyncExecutor
-keepclassmembers class * extends org.greenrobot.eventbus.util.ThrowableFailureEvent
<init>(java.lang.Throwable);
【讨论】:
这似乎有很多与问题无关的规则。我应该使用哪些部件?【参考方案4】:根据 rerofit 3.8.1
-dontwarn okio.**
-dontwarn javax.annotation.**
-dontwarn retrofit2.Platform$Java8
【讨论】:
-dontwarn javax.annotation.** 我错过了这一行。非常感谢。【参考方案5】:当前的 Proguard 规则(截至 12 月 18 日)为 here。
# Retrofit does reflection on generic parameters. InnerClasses is required to use Signature and
# EnclosingMethod is required to use InnerClasses.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Retain service method parameters when optimizing.
-keepclassmembers,allowshrinking,allowobfuscation interface *
@retrofit2.http.* <methods>;
# Ignore annotation used for build tooling.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Ignore JSR 305 annotations for embedding nullability information.
-dontwarn javax.annotation.**
# Guarded by a NoClassDefFoundError try/catch and only used when on the classpath.
-dontwarn kotlin.Unit
# Top-level functions that can only be used by Kotlin.
-dontwarn retrofit2.-KotlinExtensions
【讨论】:
【参考方案6】:我注意到为每个类添加@Keep
的注释确实可以解决所有问题,但也不会更改我设置的所有内容的名称。
所以,我的解决方案有点不同:
将所有请求、响应和他们需要(保存数据)的类放入某个文件夹(或文件夹,如果您想更有条理),并在“proguard-rules.pro”文件中创建 Proguard 规则:
-keep,allowobfuscation class com.your_library.rest_objects.** *;
或者,如果由于某种原因这不起作用,您可以使用它(来自here):
-keep public class *
public protected *;
另外,如果你构建一个混淆库,你应该把它(第二个,而不是带有“allowobfuscation”的那个)放在“consumer-rules.pro”中,并确保在它的 gradle 文件中有这个:
buildTypes
release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// https://developer.android.com/studio/projects/android-library
consumerProguardFiles 'consumer-rules.pro'
【讨论】:
【参考方案7】:对于 retrofit 和 GSON,您需要在 proguard-rules.pro
文件中添加以下规则
对于改造请添加以下规则
# Retrofit
-dontwarn retrofit2.**
-dontwarn org.codehaus.mojo.**
-keep class retrofit2.** *;
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepattributes RuntimeVisibleAnnotations
-keepattributes RuntimeInvisibleAnnotations
-keepattributes RuntimeVisibleParameterAnnotations
-keepattributes RuntimeInvisibleParameterAnnotations
-keepattributes EnclosingMethod
-keepclasseswithmembers class *
@retrofit2.* <methods>;
-keepclasseswithmembers interface *
@retrofit2.* <methods>;
# Platform calls Class.forName on types which do not exist on Android to determine platform.
-dontnote retrofit2.Platform
# Platform used when running on RoboVM on iOS. Will not be used at runtime.
-dontnote retrofit2.Platform$IOS$MainThreadExecutor
# Platform used when running on Java 8 VMs. Will not be used at runtime.
-dontwarn retrofit2.Platform$Java8
# Retain generic type information for use by reflection by converters and adapters.
-keepattributes Signature
# Retain declared checked exceptions for use by a Proxy instance.
-keepattributes Exceptions
对于GSON请添加以下规则
##--- Begin:GSON ----
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON @Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe *;
#-keep class com.google.gson.stream.** *;
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** *;
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
# keep enum so gson can deserialize it
-keepclassmembers enum * *;
# Application classes that will be serialized/deserialized over Gson
-keep class net.mreunionlabs.wob.model.request.** *;
-keep class net.mreunionlabs.wob.model.response.** *;
-keep class net.mreunionlabs.wob.model.gson.** *;
##--- End:GSON ----
##--- End:GSON ----
【讨论】:
以上是关于Android - Proguard 和改造 2?的主要内容,如果未能解决你的问题,请参考以下文章