如何从静态上下文中获取资源内容?
我想在对小部件执行诸如 setText
之类的其他操作之前从 xml
文件中读取字符串,那么如果没有活动对象来调用 ,我该如何做到这一点getResources() 上吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
我想在对小部件执行诸如 setText
之类的其他操作之前从 xml
文件中读取字符串,那么如果没有活动对象来调用 ,我该如何做到这一点getResources() 上吗?
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(17)
Application
的子类,例如public类App extends Application {
将AndroidManifest.xml
中
标记的android:name
属性设置为指向您的新类,例如android:name=".App"
onCreate()
方法中,保存您的上下文(例如this
) 到一个名为mContext
的静态字段,并创建一个返回该字段的静态方法,例如getContext()
:它应该是这样的:
现在您可以使用: <每当您想要获取上下文时,请使用 code>App.getContext() ,然后使用
getResources()
(或App.getContext().getResources()
) 。Application
, for instancepublic class App extends Application {
android:name
attribute of your<application>
tag in theAndroidManifest.xml
to point to your new class, e.g.android:name=".App"
onCreate()
method of your app instance, save your context (e.g.this
) to a static field namedmContext
and create a static method that returns this field, e.g.getContext()
:This is how it should look:
Now you can use:
App.getContext()
whenever you want to get a context, and thengetResources()
(orApp.getContext().getResources()
).仅适用于系统资源!
使用
您可以在应用程序中的任何地方使用它们,甚至在静态常量声明中!
For system resources only!
Use
You can use them everywhere in your application, even in static constants declarations!
我的 Kotlin 解决方案是使用静态应用程序上下文:
以及我到处使用的 Strings 类:
这样您就可以有一种干净的方式来获取资源字符串
请不要删除这个答案,让我保留一个。
My Kotlin solution is to use a static Application context:
And the Strings class, that I use everywhere:
So you can have a clean way of getting resource strings
Please don't delete this answer, let me keep one.
快捷方式
我使用
App.getRes()
而不是App.getContext().getResources()
(如 @Cristian 回答)在任何地方使用都非常简单您的代码!
因此,这是一个独特的解决方案,您可以通过它从任何地方访问资源,例如
Util class
。(1) 创建或编辑您的
Application
类。(2) 将名称字段添加到 标记中。 (或者如果已经存在则跳过此)
manifest.xml
现在您可以开始了。
在代码中的任何位置使用
App.getRes().getString(R.string.some_id)
。Shortcut
I use
App.getRes()
instead ofApp.getContext().getResources()
(as @Cristian answered)It is very simple to use anywhere in your code!
So here is a unique solution by which you can access resources from anywhere like
Util class
.(1) Create or Edit your
Application
class.(2) Add name field to your
manifest.xml
<application
tag. (or Skip this if already there)Now you are good to go.
Use
App.getRes().getString(R.string.some_id)
anywhere in code.还有另一种可能性。我从这样的资源加载 OpenGL 着色器:
如您所见,您可以访问路径
/res/...
中的任何资源将
aClass
更改为您的类。这也是我在测试中加载资源的方式(androidTests)There is also another possibilty. I load OpenGl shaders from resources like this:
As you can see, you can access any resource in path
/res/...
Change
aClass
to your class. This also how I load resources in tests (androidTests)Singleton:
在您的
Application
子类中初始化 Singleton:如果我没记错的话,这会为您提供一个到 applicationContext 的钩子,使用
ApplicationContextSingleton.getInstance.getApplicationContext(); 调用它代码>
您不需要在任何时候清除它,因为当应用程序关闭时,它会随之消失。
请记住更新
AndroidManifest.xml
以使用此Application
子类:现在您也应该能够从任何地方使用 ApplicationContextSingleton.getInstance().getApplicationContext().getResources()应用程序子类无法做到的极少数地方。
如果您发现这里有什么问题请告诉我,谢谢。 :)
The Singleton:
Initialize the Singleton in your
Application
subclass:If I´m not wrong, this gives you a hook to applicationContext everywhere, call it with
ApplicationContextSingleton.getInstance.getApplicationContext();
You shouldn´t need to clear this at any point, as when application closes, this goes with it anyway.
Remember to update
AndroidManifest.xml
to use thisApplication
subclass:Now you should be able to use ApplicationContextSingleton.getInstance().getApplicationContext().getResources() from anywhere, also the very few places where application subclasses can´t.
Please let me know if you see anything wrong here, thank you. :)
另一个解决方案:
如果非静态外部类中有静态子类,则可以通过外部类中的静态变量从子类内部访问资源,这些静态变量在创建外部类时进行初始化。就像
我将它用于 FragmentActivity 中静态 FragmentPagerAdapter 的 getPageTitle(intposition) 函数一样,由于 I8N,它很有用。
Another solution:
If you have a static subclass in a non-static outer class, you can access the resources from within the subclass via static variables in the outer class, which you initialise on creation of the outer class. Like
I used it for the getPageTitle(int position) Function of the static FragmentPagerAdapter within my FragmentActivity which is useful because of I8N.
我想,还有更多的办法。
但有时,我会使用这种解决方案。 (全球完整):
I think, more way is possible.
But sometimes, I using this solution. (full global):
我从静态函数加载 openGL ES 的着色器。
请记住文件名和目录名必须使用小写,否则操作将失败
I load shader for openGL ES from static function.
Remember you must use lower case for your file and directory name, or else the operation will be failed
我正在使用 API 级别 27,经过大约两天的努力,找到了最佳解决方案。如果您想从不是从 Activity 或 Application 派生的类中读取 xml 文件,请执行以下操作。
将 testdata.xml 文件放入资产目录中。
编写以下代码来解析测试数据文档。
I am using API level 27 and found a best solution after struggling for around two days. If you want to read a xml file from a class which doesn't derive from Activity or Application then do the following.
Put the testdata.xml file inside the assets directory.
Write the following code to get the testdata document parsed.
在没有上下文的情况下将图像资源作为 InputStream 获取:
如果您需要文件的目录树,它也可以工作(资产支持子目录):
Getting image resouse as InputStream without context:
If you need derectory tree for your files, it will also works (assets supports sub-dirs):
为什么你不尝试
why you dont try
这是您可以尝试的另一种略有不同的方法。
您可以像其他解决方案提到的那样对
Application
类进行子类化,并存储对Resources
实例的静态引用。创建一个应用程序类并在
onCreate
方法中初始化Resources
变量。当您的应用程序启动时将调用此函数。我们可以在这里使用WeakReference
来防止由于将此实例存储为静态变量而可能发生的内存泄漏(尽管这种情况不太可能发生),因为您提到您只想从中检索字符串xml资源声明,不需要将此资源变量暴露给其他类,用于资源实例的封装,防止泄露。因此,您可以将引用存储为私有变量。
请记住在
onCreate
中初始化此变量:我们还需要将应用程序的
android:name
声明为.App
(或您设置的任何其他名称)到)在AndroidManifest.xml
中的application
标记下。检索字符串资源的另一种方法不是使用其他类中的
Resources
实例(或Context
实例),而是获取App
类以静态方法为您获取此信息。这使实例保持封装/私有。您可以在
App
类中使用静态方法来检索这些值(例如getStringGlobal
,只是不要调用它getString
,因为它会与默认方法)如所见,您还可以添加错误处理,以防
Resources
的实例不可用(这不应该发生,但以防万一)。来检索字符串资源:
然后,您可以通过调用您的
App.java
Here is an alternative, slightly different, approach that you may try.
You could subclass the
Application
class like what other solutions mentioned, and store a static reference to an instance ofResources
.Create an application class and initialise the
Resources
variable in theonCreate
method. This will be called when your app starts. We can useWeakReference
here to prevent memory leaks that might happen as a result of storing this instance as a static variable(although it is very unlikely to happen)Since you mentioned that you only want to retrieve strings from the xml resource declaration, there is no need to expose this resource variable to other classes, for encapsulation of the resources instance and to prevent it from leaking out. Hence, you may store the reference as a private variable.
Remember to initialise this variable in
onCreate
:We also need to declare the application's
android:name
as.App
(or any other name you set it to) inAndroidManifest.xml
under theapplication
tag.Another way of retrieving the string resource is not by using the
Resources
instance in other classes(or theContext
instance), but to get theApp
class to get this for you in a static method. This keeps the instance encapsulated/private.You can use a static method in your
App
class to retrieve these values(e.g.getStringGlobal
, just do not call itgetString
as it will conflict with the default method)As seen, you can also add error handling in case the instance of
Resources
is not available(this should not happen, but just in case).You can then retrieve the string resource by calling
So your
App.java
:从静态上下文获取资源的另一个选择是将类的上下文作为参数解析到函数中。
例如:
Another option to get a resource from a static context would be to parse the context of your class into the function as an argument.
For example:
在您实现静态函数的类中,您可以从该类调用private\public方法。 private\public 方法可以访问getResources。
例如:
并且从其他类\活动中,您可以调用:
In your class, where you implement the static function, you can call a private\public method from this class. The private\public method can access the getResources.
for example:
and from other class\activity, you can call:
如果你有上下文,我的意思是里面;
您可以使用此代码来获取资源:
if you have a context, i mean inside;
you can use this code to get resources: