如何从Android的另一个应用程序资源更改主题?

我知道有一种方法来设置主题,通过在styles.xml中定义并使用它

setTheme(android.R.style.MyTheme); 

不过,我想从我开发的另一个应用程序获取主题。 我知道资源名称,实际上我能够获得这个代码块的主题ID;

 Resources res = getPackageManager().getResourcesForApplication("com.example.theme"); int resThemeId = res.getIdentifier("my_theme","style","com.example.theme"); 

当我debugging时,我看到resThemeId不是零。

然后,我需要最后的命令来设置这个主题。 在super.onCreate()函数之前,我试图实现这个方法,但似乎不工作

 setTheme(resThemeId); 

但是,而不是这个,如果我写下面的声明,我工作正常

 setTheme(android.R.style.Theme_Holo_Light); 

那么,我应该怎么做才能使用来自不同软件包资源的主题呢?

那么,我应该怎么做才能使用来自不同软件包资源的主题呢?

你不应该这样做,原因很多。 我写了一个简单的项目,显示只要包中包含您的活动使用的资源,就可以。

请参阅: https : //github.com/jaredrummler/SO-41872033


基本上,您需要从活动中返回包的资源:

 public class MainActivity extends AppCompatActivity { Resources resources; @Override protected void onCreate(Bundle savedInstanceState) { int themeResId = getResources().getIdentifier("AppTheme", "style", "com.example.theme"); if (themeResId != 0) { setTheme(themeResId); } super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public Resources getResources() { if (resources == null) { try { resources = getPackageManager().getResourcesForApplication("com.example.theme"); } catch (PackageManager.NameNotFoundException e) { resources = super.getResources(); } } return resources; } } 

这只是为了表明这是可能的。 再一次,我build议你避免这个。

正如已经在评论中提到的那样,您可以从其他应用程序访问资源,但使用其他应用程序主题将无法工作。


由于certificate总是一件好事,让我们来看看源代码(我使用API​​ 24来源)

调用Activity上的setTheme()将调用ContextThemeWrapper父类中的initializeTheme() ,最终调用onApplyThemeResource(..) ,后者将尝试从资源加载实际的主题数据,方法是调用theme.applyStyle(resId, true)

在通过包装器Resources.Theme的链之后,我们可以在ResourcesImpl.ThemeImpl看到以下内容,其中AssetManager被调用以将样式加载到主题中:

 void applyStyle(int resId, boolean force) { synchronized (mKey) { AssetManager.applyThemeStyle(mTheme, resId, force); mThemeResId = resId; mKey.append(resId, force); } } 

这是你尝试的地方,无法从你的其他应用程序加载外国主题。


因为你需要使用的大多数方法都是静态调用或者封装本地方法,所以似乎没有什么办法可以实现你想要的(例如应用或者创build一个新的主题)

即使通过在上下文中使用getAssets()getAssets()其他应用程序的AssetManager , 也没有可访问的方法来创build或应用主题 。

所以使用其他应用程序的资源的唯一方法是将资源添加到您的资源。

你有没有看过这个演示: 多个主题材质devise

您可以检查此演示的运行时主题更改。

希望它会帮助你。