Как изменить тему из другого ресурса приложения в Android?

Я знаю, что есть способ задать темы, определяя в styles.xml и использовать его так

setTheme(android.R.style.MyTheme); 

Тем не менее, я хочу получить темы из другого приложения, которое я разработал. Я знаю имена ресурсов, и на самом деле я могу получить идентификатор темы с этим блоком кода;

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

Когда я отлаживаю, я вижу, что 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; } } 

Это просто, чтобы показать, что это возможно. Опять же, я рекомендую вам избежать этого.

Как уже упоминалось в комментарии, вы можете получить доступ к ресурсам из других приложений, но использование другой темы приложения не будет работать.


Поскольку наличие доказательств всегда хорошо, давайте посмотрим на исходный код (я использовал источники API 24)

Вызов setTheme() в Activity вызовет initializeTheme() в родительском классе ContextThemeWrapper , который в конечном итоге 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); } } 

Здесь вы пытаетесь загрузить внешнюю тему из другого приложения.


Поскольку большинство методов, которые вам нужно использовать, это статические вызовы или локальные методы пакета, не кажется, что есть какой-либо способ достичь того, что вы хотите (например, применение или создание новой темы)

Даже если вы AssetManager другого приложения, используя getAssets() в контексте, нет никакого доступного метода для создания или применения тем .

Таким образом, единственный способ использовать ресурсы другого приложения – это добавить ресурсы к вашим.

Вы видели эту демонстрацию: Несколько тематических материалов

Вы можете проверить эту демонстрацию для изменения темы времени исполнения.

Надеюсь, это поможет вам.