Android RecyclerView和Gson混淆问题

RecyclerView 配置混淆

release打包后发现RecyclerView不显示数据, 推测是反射没有加混淆问题, 具体置如下

# When layoutManager xml attribute is used, RecyclerView inflates
#LayoutManagers' constructors using reflection.
-keep public class * extends androidx.recyclerview.widget.RecyclerView$LayoutManager {
    public <init>(android.content.Context, android.util.AttributeSet, int, int);
    public <init>();
}
-keepclassmembers class androidx.recyclerview.widget.RecyclerView {
    public void suppressLayout(boolean);
    public boolean isLayoutSuppressed();
}

源码查证

RecyclerView反射创建LayoutManager的过程 :

//androidx.recyclerview.widget.RecyclerView

/**
 * Instantiate and set a LayoutManager, if specified in the attributes.
 */
private void createLayoutManager(Context context, String className, AttributeSet attrs,
        int defStyleAttr, int defStyleRes) {
    if (className != null) {
        className = className.trim();
        if (!className.isEmpty()) {
            className = getFullClassName(context, className);
            try {
                ClassLoader classLoader;
                if (isInEditMode()) {
                    // Stupid layoutlib cannot handle simple class loaders.
                    classLoader = this.getClass().getClassLoader();
                } else {
                    classLoader = context.getClassLoader();
                }
                Class<? extends LayoutManager> layoutManagerClass =
                        Class.forName(className, false, classLoader)
                                .asSubclass(LayoutManager.class);
                Constructor<? extends LayoutManager> constructor;
                Object[] constructorArgs = null;
                try {
                    constructor = layoutManagerClass
                            .getConstructor(LAYOUT_MANAGER_CONSTRUCTOR_SIGNATURE);
                    constructorArgs = new Object[]{context, attrs, defStyleAttr, defStyleRes};
                } catch (NoSuchMethodException e) {
                    try {
                        constructor = layoutManagerClass.getConstructor();
                    } catch (NoSuchMethodException e1) {
                        e1.initCause(e);
                        throw new IllegalStateException(attrs.getPositionDescription()
                                + ": Error creating LayoutManager " + className, e1);
                    }
                }
                constructor.setAccessible(true);
                setLayoutManager(constructor.newInstance(constructorArgs));
            } catch (ClassNotFoundException e) {
                throw new IllegalStateException(attrs.getPositionDescription()
                        + ": Unable to find LayoutManager " + className, e);
            } catch (InvocationTargetException e) {
                throw new IllegalStateException(attrs.getPositionDescription()
                        + ": Could not instantiate the LayoutManager: " + className, e);
            } catch (InstantiationException e) {
                throw new IllegalStateException(attrs.getPositionDescription()
                        + ": Could not instantiate the LayoutManager: " + className, e);
            } catch (IllegalAccessException e) {
                throw new IllegalStateException(attrs.getPositionDescription()
                        + ": Cannot access non-public constructor " + className, e);
            } catch (ClassCastException e) {
                throw new IllegalStateException(attrs.getPositionDescription()
                        + ": Class is not a LayoutManager " + className, e);
            }
        }
    }
}

参考: android.googlesource.com/platform/fr…


Gson混淆配置

##---------------Begin: proguard configuration for 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
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }
-keep class com.xxx.client.bean.Cctv{ <fields>; }
-keep class com.xxx.client.bean.CctvItem{ <fields>; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
  @com.google.gson.annotations.SerializedName <fields>;
}
##---------------End: proguard configuration for Gson  ----------

其中以下这两句用来防止Gson解析的实体被混淆 Gson().fromJson(jsonCCTV, Cctv::class.java) :

-keep class com.xxx.client.bean.Cctv{ <fields>; }
-keep class com.xxx.client.bean.CctvItem{ <fields>; }
posted @ 2020-12-07 17:06  javakam  阅读(0)  评论(0)    收藏  举报  来源