下面列出了android.content.res.Resources#newTheme() 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
protected void loadResources(String dexPath) {
try {
AssetManager assetManager = AssetManager.class.newInstance();
Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
addAssetPath.invoke(assetManager, dexPath);
mAssetManager = assetManager;
} catch (Exception e) {
Log.i("inject", "loadResource error:" + Log.getStackTraceString(e));
e.printStackTrace();
}
Resources superRes = super.getResources();
superRes.getDisplayMetrics();
superRes.getConfiguration();
mResources = new Resources(mAssetManager, superRes.getDisplayMetrics(), superRes.getConfiguration());
mTheme = mResources.newTheme();
mTheme.setTo(super.getTheme());
}
@Nullable
public Drawable getIcon(Context context) {
Resources resources = null;
PackageInfo packageInfo = null;
try {
resources = context.getPackageManager().getResourcesForApplication(packageName);
packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException ignored) {
}
if (resources == null || packageInfo == null) return null;
Resources.Theme theme = resources.newTheme();
theme.applyStyle(packageInfo.applicationInfo.theme, false);
try {
return ResourcesCompat.getDrawable(resources, getIcon(), theme);
} catch (Resources.NotFoundException e) {
return null;
}
}
@Nullable
private Drawable getDrawable(Context context, int resource, String packageName) {
if (packageName == null) return null;
Resources resources = null;
PackageInfo packageInfo = null;
try {
resources = context.getPackageManager().getResourcesForApplication(packageName);
packageInfo = context.getPackageManager().getPackageInfo(packageName, PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException ignored) {
}
if (resources == null || packageInfo == null) return null;
Resources.Theme theme = resources.newTheme();
theme.applyStyle(packageInfo.applicationInfo.theme, false);
try {
return ResourcesCompat.getDrawable(resources, resource, theme);
} catch (Resources.NotFoundException | OutOfMemoryError e) {
return null;
}
}
public static void hookActivityResources(Activity activity, String packageName) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && isVivo(activity.getResources())) {
// for 5.0+ vivo
return;
}
// designed for 5.0 - only, but some bad phones not work, eg:letv
try {
Context base = activity.getBaseContext();
final LoadedPlugin plugin = PluginManager.getInstance(activity).getLoadedPlugin(packageName);
final Resources resources = plugin.getResources();
if (resources != null) {
Reflector.with(base).field("mResources").set(resources);
// copy theme
Resources.Theme theme = resources.newTheme();
theme.setTo(activity.getTheme());
Reflector reflector = Reflector.with(activity);
int themeResource = reflector.field("mThemeResource").get();
theme.applyStyle(themeResource, true);
reflector.field("mTheme").set(theme);
reflector.field("mResources").set(resources);
}
} catch (Exception e) {
Log.w(Constants.TAG, e);
}
}
public void applyThemeToActivity(Activity activity) {
if (currentCustomThemePatcher == null && currentCustomTheme != null) {
ThemeResourceFileBuilder.CustomTheme theme = ThemeResourceFileBuilder
.createTheme(context, currentCustomTheme);
currentTheme = theme;
File themeFile = ThemeResourceFileBuilder.createThemeZipFile(context,
theme.getResTable());
currentCustomThemePatcher = new Theme(context, themeFile.getAbsolutePath());
}
ThemeResInfo currentBaseTheme = currentTheme;
if (currentCustomTheme != null)
currentBaseTheme = currentCustomTheme.baseThemeInfo;
boolean isThemeDark = currentBaseTheme instanceof BaseTheme &&
((BaseTheme) currentBaseTheme).isDark;
if (currentCustomThemePatcher == null && isThemeDark) {
currentCustomThemePatcher = new Theme(activity.getAssets());
}
if (mNeedsApplyIrcColors) {
Configuration c = new Configuration();
c.setToDefaults();
c.uiMode = Configuration.UI_MODE_TYPE_NORMAL;
if (currentBaseTheme instanceof BaseTheme && ((BaseTheme) currentBaseTheme).isDark)
c.uiMode |= Configuration.UI_MODE_NIGHT_YES;
Resources r = new Resources(currentCustomThemePatcher != null ?
currentCustomThemePatcher.getAssetManager() : context.getAssets(),
new DisplayMetrics(), c);
Resources.Theme t = r.newTheme();
ThemeResInfo resInfo = currentTheme != null ? currentTheme : fallbackTheme;
t.applyStyle(resInfo.getThemeResId(), true);
IRCColorUtils.loadColors(t, resInfo.getIRCColorsResId());
mNeedsApplyIrcColors = false;
}
if (currentCustomThemePatcher != null) {
currentCustomThemePatcher.applyToActivity(activity);
}
if (isThemeDark)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES);
else
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO);
}
protected void loadResources() throws InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, NoSuchFieldException {
Log.d(TAG, "MyApplication : loadResources()");
AssetManager am = (AssetManager) AssetManager.class.newInstance();
am.getClass().getMethod("addAssetPath", String.class).invoke(am, dexPath);
mAssetManager = am;
Constructor<?> constructor_Resources = Resources.class.getConstructor(AssetManager.class, cc.getResources()
.getDisplayMetrics().getClass(), cc.getResources().getConfiguration().getClass());
mResources = (Resources) constructor_Resources.newInstance(am, cc.getResources().getDisplayMetrics(), cc.getResources().getConfiguration());
mTheme = mResources.newTheme();
mTheme.applyStyle(android.R.style.Theme_Light_NoTitleBar_Fullscreen, true);
}
@Override
public boolean add(V object) {
WeakReference ref = (WeakReference)object;
Object tintContextWrapper = ref.get();
if (tintContextWrapper != null) {
Resources resources = ((ContextWrapper)tintContextWrapper).getBaseContext().getResources();
RefInvoker.setField(tintContextWrapper, TintContextWrapper, "mResources", resources);
Resources.Theme theme = resources.newTheme();
theme.setTo(((ContextWrapper)tintContextWrapper).getBaseContext().getTheme());
RefInvoker.setField(tintContextWrapper, TintContextWrapper, "mTheme", theme);
}
return super.add(object);
}
/**
* 创建插件的Resource {@link ResourcesProxy},通过此Resource对象
* 插件可以访问主工程和插件的资源
*/
private void createPluginResource() {
PluginDebugLog.runtimeLog(TAG, "createPluginResource for " + mPluginPackageName);
PackageManager pm = mHostContext.getPackageManager();
AssetManager am = null;
try {
Class<?>[] paramTypes = new Class[]{String.class};
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
// Android 5.0以下系统方法创建的AssetManager不支持扩展资源表,始终new出来
am = AssetManager.class.newInstance();
ReflectionUtils.on(am).call("addAssetPath", sMethods, paramTypes, mPluginPath);
} else {
// Android 5.0以上使用PackageManager的公开方法创建, 避免反射
Resources resources = pm.getResourcesForApplication(mPluginPackageInfo.getApplicationInfo());
am = resources.getAssets();
}
boolean shouldAddHostRes = !mPluginPackageInfo.isIndividualMode() && mPluginPackageInfo.isResourceNeedMerge();
if (shouldAddHostRes) {
// 添加宿主的资源到插件的AssetManager
ReflectionUtils.on(am).call("addAssetPath", sMethods, paramTypes,
mHostContext.getApplicationInfo().sourceDir);
PluginDebugLog.runtimeLog(TAG, "--- Resource merging into plugin @ " + mPluginPackageInfo.getPackageName());
}
// 添加系统Webview资源, Android L+
if (mPluginPackageInfo.isNeedAddWebviewResource()) {
addWebviewAssetPath(am);
}
mPluginAssetManager = am;
} catch (Exception e) {
ErrorUtil.throwErrorIfNeed(e);
String errMsg = "create plugin resources failed: " + e.getMessage();
PluginManager.deliver(mHostContext, false, mPluginPackageName, ErrorType.ERROR_PLUGIN_INIT_RESOURCES, errMsg);
}
Configuration config = new Configuration();
config.setTo(mHostResource.getConfiguration());
if (mPluginPackageInfo.isIndividualMode()) {
// 独立插件包,不依赖宿主的Resource
mPluginResource = new Resources(mPluginAssetManager, mHostResource.getDisplayMetrics(),
config);
} else {
mPluginResource = new ResourcesProxy(mPluginAssetManager, mHostResource.getDisplayMetrics(),
config, mHostResource, mPluginPackageName);
}
mPluginTheme = mPluginResource.newTheme();
mPluginTheme.setTo(mHostContext.getTheme());
mResourceTool = new ResourcesToolForPlugin(mHostContext);
}
/**
* 获取一个占位activity
*
* @param pluginActivity 插件activity
* @param launchMode 插件activity启动模式
* @param isFixed 是否建立固定映射关系
* @return 占位activity
* @throws ProxyActivityLessException 占位activity不够异常
*/
private String findActivity(String pluginActivity, int launchMode, boolean isFixed)
throws ProxyActivityLessException {
String activity = MODE_STANDARD;
ActivityPool pool = null;
switch (launchMode) {
case ActivityInfo.LAUNCH_MULTIPLE:
final PhantomCore phantomCore = PhantomCore.getInstance();
final ComponentName componentName = ComponentName.unflattenFromString(pluginActivity);
if (componentName != null) {
final ActivityInfo ai = phantomCore.findActivityInfo(componentName);
final PluginInfo pluginInfo = phantomCore.findPluginInfoByActivityName(componentName);
final int themeResourceId = ai == null ? -1 : ai.getThemeResource();
if (themeResourceId != -1 && pluginInfo != null) {
final Resources resources = pluginInfo.getPluginResources();
if (resources != null) {
final Resources.Theme theme = resources.newTheme();
theme.applyStyle(themeResourceId, true);
final TypedArray sa = theme.obtainStyledAttributes(
new int[]{android.R.attr.windowIsTranslucent});
final boolean translucent = sa.getBoolean(0, false);
sa.recycle();
activity = translucent ? MODE_STANDARD_TRANSLUCENT : MODE_STANDARD;
}
}
}
break;
case ActivityInfo.LAUNCH_SINGLE_TOP:
pool = mSingleTopPool;
break;
case ActivityInfo.LAUNCH_SINGLE_INSTANCE:
pool = mSingleInstancePool;
break;
case ActivityInfo.LAUNCH_SINGLE_TASK:
pool = mSingleTaskPool;
break;
default:
break;
}
if (null != pool) {
activity = isFixed ? pool.resolveFixedActivity(pluginActivity) : pool.resolveActivity(pluginActivity);
}
String msg = String.format("resolve %s Activity for %s proxy is %s, fixed is %s",
launchModeToString(launchMode), pluginActivity, activity, isFixed);
VLog.d(msg);
if (null == activity) {
//占位activity不够使用, 这种情况不做处理,宿主提供足够的占位activity
//这里不做主动回收,如果做主动回收可能会使程序正常执行流程发送改变
ProxyActivityLessException pae = new ProxyActivityLessException(msg);
LogReporter.reportException(pae, null);
mCache.clean();
throw pae;
}
return activity;
}