没有上下文如何访问资源

35

我想将配置(如URL等)放入资源文件夹中供实用程序类使用。然而,我不想在各处传递上下文。我希望能够通过路径名访问资源(似乎assets/是为此设计的),而不使用上下文访问资源。

在这种情况下,我希望一个单例在实例化时使用配置中的某些内容。除了实例化期间需要这一个之外,它不需要来自资源的任何东西。因此,每次调用getInstance()时都必须传递上下文是完全浪费的。

此外,这是特定于应用程序的配置,不应存储在共享系统文件或其他任何地方。


请参考 https://dev59.com/n2855IYBdhLWcg3wXC5-#58627769 中的 Kotlin 解决方案和 Application 上下文。 - CoolMind
5个回答

92

使用

Resources.getSystem().getString(android.R.string.someuniversalstuff)

你可以在应用程序中绝对任何地方使用它,甚至可以在静态常量声明中使用!但仅适用于系统资源

对于本地资源,请使用那个解决方案


54
仅限于系统资源。 - Youngjae
@Youngjae 是的。对于本地的,请按照参考文献进行操作。 - Gangnus
我收到了一个异常:android.content.res.Resources$NotFoundException:字符串资源ID。 - vinidog
6
这个答案有误导性,问题是指本地资源。 - Abhijit
@Abhijit 有两个答案。如果你不喜欢第一个,可以参考第二个答案。因此,它并不是误导,相反,它会引导你找到正确的解决方案。 - Gangnus
显示剩余2条评论

16

你可以扩展主应用程序类并提供通用助手来访问资源。这样可以解除对上下文的依赖,因为应用程序会提供上下文而不是调用者。应用程序类采用单例模式,并且在您的应用程序的任何部分运行时(包括服务)始终可用。

public class MyApplication extends Application {
 protected static MyApplication instance;

 @Override
 public void onCreate() {
  super.onCreate();
  instance = this;
 }

 public static Resources getResources() {
  return instance.getResources();
 }
}

这使您可以访问:

MyApplication.getResources()....

请确保在你的清单文件中声明自定义应用程序,以便访问此功能。假设你的自定义应用程序位于应用程序命名空间的根目录下:

<application
 android:name=".MyApplication"
 ... >

1
使用这个有没有潜在的缺点? - Mark O'Sullivan
1
尝试做这个,但不幸的是关于清单,我不知道“...”应该是什么,或者这个代码块是否应该替换、合并还是添加到现有的应用程序代码块中。 - Nerdy Bunz
在您的清单文件中的<application>标签中,只需使用您的Application类替换或添加name属性即可。 - Pablo R.

2
我建议采取以下措施: 不要在各处传递上下文,而是将您的活动类设为单例类,并具有返回上下文的公共函数:
private static ActivityMain instance;

在super.onCreate()之前在onCreate()内进行初始化:

instance = this;

然后在你的Activity中添加以下公共函数:
/** Get singleton instance of activity **/
public static ActivityMain getInstance() {
    return instance;
}

/** Returns context of this activity **/
public static Context getContext(){
    return instance.getApplicationContext();
}

现在你可以在任何类中的任何地方使用以下内容:
Context context = AntiMorphActivity.getContext();
String packageName = context.getPackageName();
int id = context.getResources().getIdentifier("web_page", "raw", packageName);

极其糟糕的解决方案。你这样泄漏了你的活动。 - Dmitry Ryadnenko
3
不,他正在使用应用程序上下文,因此活动不会泄漏。 - Davor
我刚刚使用了这个,它可以工作!但是为什么这不同于传递上下文呢?我对Android非常陌生。 - Peter G. Williams

1

很遗憾,我认为没有真正的解决方法。我会像这样布置我的代码,并传递getApplicationContext()而不是活动上下文。

public static AppController getAppController(Context context){
    if(self == null) {
        //Create instance
        self = new AppController();
    }

    return self;
}

然后:

appController = AppController.getAppController(getApplicationContext());

哦,好吧,我就怕答案会是这样。只能从上下文中访问应用程序资源似乎是相当糟糕的设计。我相信有理由... 但仍然很烦人。谢谢你确认了这个问题 =) - mnemy
1
我和我的团队总是抱怨,这使得编写松耦合模块化代码变得困难。 - sgarman

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接