我想创建一个静态哈希表,将字符串转换为整数。需要注意的是,我想在 XML文件中的几个列表中使用 strings 我定义为资源。
我只能使用资源ID来写这个:
public class MyActivity extends Activity {
private static Map<Integer, Integer> views = new HashMap<Integer, Integer>();
static {
views.put(R.string.full_text, MessageTable.VIEW_FULL);
views.put(R.string.only_text, MessageTable.VIEW_MSG);
views.put(R.string.tag_text, MessageTable.VIEW_TAGMSG);
}
我没有错误,但我真正需要做的是这样的事情:
public class MyActivity extends Activity {
private static Map<String, Integer> views = new HashMap<String, Integer>();
static {
views.put(getResources().getString(R.string.full_text), MessageTable.VIEW_FULL);
views.put(getResources().getString(R.string.only_text), MessageTable.VIEW_MSG);
views.put(getResources().getString(R.string.tag_text), MessageTable.VIEW_TAGMSG);
}
在Eclipse中给出了以下错误:
Cannot make a static reference to the non-static method getResources() from the type ContextWrapper
这条消息很有意义,但没有意义的是资源无法通过静态块访问,人们会认为静态变量是自定义创建的,以利用资源。
我想我可以在对象构造函数中填充哈希表,但这意味着要在错误的位置执行。
答案 0 :(得分:11)
getResources()
(〜MyActivity.this.getResources()
的缩写)需要一个当时未初始化的上下文对象。由于上下文仅在您点击onCreate
后才可用,因此您无法在MyActivity
的构建时间执行此操作。
原因是实例化MyActivity
类的活动管理器必须先确定配置(方向,屏幕大小,语言等),然后才能知道必须从xml中提取哪些资源。 - &GT;资源不是静态的,无法从静态上下文访问。
所以我想在onCreate
或更晚的时候没有办法做这些操作。
编辑:虽然您当然可以从Context
更新静态HashMap(或静态onCreate
),但我不建议您这样做,因为您可能有多个相同Activity的实例,可能不同/更改配置。同时存储静态Context
是创建Memory Leak
答案 1 :(得分:6)
public Static Resources mResources;
public MyApplication extends Application
{
@Override
public void onCreate()
{
mResources = getResources();
}
}
获得对Resources的静态引用后,您可以在整个应用程序的任何位置引用它。但是我不确定这是否会引入一个妈妈的泄漏;
答案 2 :(得分:1)
您可以做的一件事是创建一个Application
类并在AndroidManifest.xml中注册它。然后重写onCreate方法并将Application类设置为静态引用,然后触摸Activity类以运行静态初始化程序。当apk被加载到内存中时将运行Application
类,因此它将始终在任何Activity
之前运行。
这有一些明显的缺点。我认为最明显的一个问题是,如果系统语言发生了变化,并且您已经为这些资源添加了翻译;然后你会有不一致的字符串,因为应用程序将使用默认/启动应用程序时的语言。字符串资源受Android资源管理系统的影响,因此对方向,系统语言,屏幕尺寸等内容的更改会影响这些值。这就是为什么在
时重置活动的原因简而言之,最好为此作业使用常量字符串键值对。如果您需要使用字符串资源,那么您可以更好地处理翻译。我每次活动开始时都会加载它们。否则,您可能会发生内存泄漏和字符串转换不一致的风险。
public MyApplication extends Application {
public static Context GlobalContext = null;
@Override
protected void onCreate() {
MyApplication.GlobalContext = this;
// Touch the activity class.
MyActivity activity = new MyActivity();
// Throw it away by not using it.
// invalidate handle to prevent GC leaks.
GlobalContext = null;
}
}
public class MyActivity extends Activity {
private static Map<String, Integer> views = new HashMap<String, Integer>();
static {
Context context = MyApplication.GlobalContext;
Resources res = context.getResources();
views.put(res.getString(R.string.full_text), MessageTable.VIEW_FULL);
views.put(res.getString(R.string.only_text), MessageTable.VIEW_MSG);
views.put(res.getString(R.string.tag_text), MessageTable.VIEW_TAGMSG);
}
}
答案 3 :(得分:0)
您始终可以保留对ApplicationContext的静态引用。这里描述了一种可能的方法:Static way to get 'Context' on Android?
答案 4 :(得分:0)
我不知道什么是最好的方式,但是,例如,在我的应用程序中,我有一个Singleton(称为GuiaUtil),远离我的当前活动和上下文。
private static Map<String, Integer> views = new HashMap<String, Integer>();
static {
views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.full_text), MessageTable.VIEW_FULL);
views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.only_text), MessageTable.VIEW_MSG);
views.put(GuiaUtil.instance().getAppContext().getResources().getString(R.string.tag_text), MessageTable.VIEW_TAGMSG);
}