如何在Android/Kotlin模块的非Activity类中调用getResources?
嘿,这个问题我之前做Android Library开发时也踩过坑,给你梳理几个实用的解决方案:
不管是宿主模块还是非宿主模块,核心都是需要一个有效的Context实例,因为getResources()是Context类的方法。常用的两种方式:
构造方法/方法参数传入Context
这是最直接也最推荐的方式,在创建非Activity类的实例时,传入Context(优先用Application Context,避免持有Activity导致内存泄漏)。示例代码:public class MyBusinessClass { private final Context mAppContext; // 构造方法传入Context,转存为Application Context public MyBusinessClass(Context context) { mAppContext = context.getApplicationContext(); } public void useResource() { // 访问资源 String tipText = mAppContext.getResources().getString(R.string.tip_message); Drawable icon = mAppContext.getResources().getDrawable(R.drawable.ic_info); } }调用的时候,在Activity或Fragment里传入
this或者getContext()就行。全局持有Application Context
如果你不想每次都传Context,可以在项目里(不管宿主还是Library)写一个全局工具类,初始化时保存Application Context,之后随时调用:public class AppContextHolder { private static Context sAppContext; // 在Application的onCreate里调用初始化 public static void init(Context context) { sAppContext = context.getApplicationContext(); } public static Context getAppContext() { if (sAppContext == null) { throw new RuntimeException("AppContextHolder未初始化,请先调用init方法!"); } return sAppContext; } // 直接封装getResources的方法 public static Resources getAppResources() { return getAppContext().getResources(); } }然后在宿主App的
Application类里添加:@Override public void onCreate() { super.onCreate(); AppContextHolder.init(this); }之后任何非Activity类都可以直接用
AppContextHolder.getAppResources()获取资源了。
你提到在非宿主模块的resource文件夹存了资源,没法直接用getApplicationContext——其实Library模块本身没有独立的Application,所以必须依赖宿主App的Context。这里额外注意三点:
访问Library自身的资源:直接用Library模块里的
R类就行(比如com.example.mylibrary.R.string.lib_custom_text),只要有Context就能获取,不需要额外操作,因为宿主编译时会把Library的资源合并到自己的资源池中。避免硬编码资源ID:不要直接用资源的int值,一定要用
R类引用,不然不同编译环境下资源ID可能变化,导致找不到资源。Library模块的全局工具类:如果Library需要独立提供资源访问能力,可以在Library内部写一个类似上面的工具类,然后要求宿主App在初始化时调用Library的初始化方法,传入Context。示例:
// Library模块里的工具类 public class LibResourceHelper { private static Context sLibAppContext; // 暴露给宿主的初始化方法 public static void init(Context context) { sLibAppContext = context.getApplicationContext(); } public static Resources getLibResources() { if (sLibAppContext == null) { throw new RuntimeException("请先调用LibResourceHelper.init()初始化!"); } return sLibAppContext.getResources(); } }宿主App的
Application里调用:@Override public void onCreate() { super.onCreate(); LibResourceHelper.init(this); }这样Library里的任何类都可以用
LibResourceHelper.getLibResources()访问资源了。
内容的提问来源于stack exchange,提问作者Sazzad Hissain Khan

