diff --git a/Android/DevSample/small/src/main/java/net/wequick/small/ApkBundleLauncher.java b/Android/DevSample/small/src/main/java/net/wequick/small/ApkBundleLauncher.java index e8f2e5d2..41186973 100644 --- a/Android/DevSample/small/src/main/java/net/wequick/small/ApkBundleLauncher.java +++ b/Android/DevSample/small/src/main/java/net/wequick/small/ApkBundleLauncher.java @@ -46,6 +46,7 @@ import net.wequick.small.internal.InstrumentationInternal; import net.wequick.small.util.HealthManager; import net.wequick.small.util.ReflectAccelerator; +import net.wequick.small.util.ResourceUtils; import java.io.File; import java.io.IOException; @@ -329,6 +330,11 @@ public void callActivityOnCreate(Activity activity, android.os.Bundle icicle) { } } + if(HealthManager.checkOpenMandatoryModeIfNeeded()){ + ResourceUtils.replaceThemeV7(activity); + ResourceUtils.replaceResources(activity); + } + sHostInstrumentation.callActivityOnCreate(activity, icicle); } diff --git a/Android/DevSample/small/src/main/java/net/wequick/small/util/HealthManager.java b/Android/DevSample/small/src/main/java/net/wequick/small/util/HealthManager.java index 10d70757..40478c32 100644 --- a/Android/DevSample/small/src/main/java/net/wequick/small/util/HealthManager.java +++ b/Android/DevSample/small/src/main/java/net/wequick/small/util/HealthManager.java @@ -16,6 +16,7 @@ package net.wequick.small.util; import android.app.Activity; +import android.content.SharedPreferences; import android.content.res.AssetManager; import android.content.res.Resources; import android.util.Log; @@ -36,6 +37,8 @@ */ public class HealthManager { + //对某些手机开启强制模式,强制替换resource、theme + public static final String MandatoryMode="MandatoryMode"; private static final String TAG = "HealthManager"; public static boolean fixException(Object obj, Throwable e) { @@ -76,6 +79,7 @@ private static void dumpAssets(Object obj, boolean isThemeError) { AssetManager assets = activity.getAssets(); AssetManager appAssets = activity.getApplication().getAssets(); if (!assets.equals(appAssets)) { + setMandatoryMode(true); err += "The activity assets are different from application.\n"; err += getAssetPathsDebugInfo(appAssets, themeId, "Application") + "\n"; err += getAssetPathsDebugInfo(assets, themeId, "Activity"); @@ -202,4 +206,25 @@ private static int getPackageId(AssetManager assets, String packageName) { } return 0; } + + + + private static void setMandatoryMode(boolean isMandatoryMode) { + SharedPreferences small = Small.getSharedPreferences(); + SharedPreferences.Editor editor = small.edit(); + if (!isMandatoryMode) { + editor.remove(MandatoryMode); + } else { + editor.putBoolean(MandatoryMode, isMandatoryMode); + } + editor.apply(); + } + + private static Boolean openMandatoryMode=null; + public static boolean checkOpenMandatoryModeIfNeeded(){ + if(openMandatoryMode==null) + openMandatoryMode=Small.getSharedPreferences().getBoolean(MandatoryMode,false); + return openMandatoryMode; + } + } diff --git a/Android/DevSample/small/src/main/java/net/wequick/small/util/ResourceUtils.java b/Android/DevSample/small/src/main/java/net/wequick/small/util/ResourceUtils.java new file mode 100644 index 00000000..e96fc118 --- /dev/null +++ b/Android/DevSample/small/src/main/java/net/wequick/small/util/ResourceUtils.java @@ -0,0 +1,81 @@ +package net.wequick.small.util; + +import android.app.Activity; +import android.content.pm.ActivityInfo; +import android.content.res.Resources; +import android.content.res.TypedArray; +import android.support.v7.app.AppCompatActivity; +import android.util.Log; +import android.view.ContextThemeWrapper; + +import net.wequick.small.R; +import net.wequick.small.Small; + +import java.lang.reflect.Field; + + +public class ResourceUtils { + + public static int findThemeResId(Activity activity) { + int themeId = 0; + try { + Field f = ContextThemeWrapper.class.getDeclaredField("mThemeResource"); + f.setAccessible(true); + themeId = (int) f.get(activity); + } catch (Exception ignored) { + } + return themeId; + } + + + public static void replaceThemeV7(Activity activity) { + if(!(activity instanceof AppCompatActivity)) + return; + + Resources.Theme theme = Small.getContext().getResources().newTheme(); + theme.applyStyle(findThemeResId(activity), true); + + Field mThemeField = null; + Class clazz = activity.getClass(); + findTheme: + do { + try { + mThemeField = clazz.getDeclaredField("mTheme"); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + clazz = clazz.getSuperclass(); + if (clazz.getName().contains("Object")) + break findTheme; + } + } while (mThemeField == null); + mThemeField.setAccessible(true); + try { + mThemeField.set(activity, theme); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public static void replaceResources(Activity activity) { + Field resField = null; + Class clazz = activity.getClass(); + findResource: + do { + try { + resField = clazz.getDeclaredField("mResources"); + } catch (NoSuchFieldException e) { + e.printStackTrace(); + clazz = clazz.getSuperclass(); + if (clazz.getName().contains("Object")) + break findResource; + } + } while (resField == null); + resField.setAccessible(true); + try { + resField.set(activity, Small.getContext().getResources()); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + +}