[英]Accessing resources in a static final array in a utility class
我有一个用于诊断(运行时信息,警告和错误事件)的实用程序类,它为所有可能的诊断定义代码,严重性级别和人类可读的消息。 还有一个DiagHolder,用于保存从数组和该数据的访问器中选择的诊断信息。
为了将R.string用于描述诊断的文本的本地化,我将重构Java中的硬编码字符串。
public class Diagnostic {
// Debugging
private static final boolean D = true; // debugging?
private static final String TAG = "Diagnostic";
static Context mContext;
DiagHolder mDiagHolder;
String mTimestamp;
public enum DIAG_TYPE{
INFO,
WARNING,
ERROR
}
public enum DIAG_CODE {
SYSTEM_ONLINE,
SELF_TEST_COMPLETE,
GPS_SYNCH,
BATTERY_50,
BATTERY_25,
UNEXPECTED_RESET,
UNKNOWN_ERROR
}
static final DiagHolder[] Diags = {
//new DiagHolder("System powered up.", DIAG_CODE.SYSTEM_ONLINE, DIAG_TYPE.INFO),
new DiagHolder(mContext.getResources().getString(R.string.SYSTEM_ONLINE), DIAG_CODE.SYSTEM_ONLINE, DIAG_TYPE.INFO),
new DiagHolder("Self test complete. No issues.", DIAG_CODE.SELF_TEST_COMPLETE, DIAG_TYPE.INFO),
new DiagHolder("GPS synchronized.", DIAG_CODE.GPS_SYNCH, DIAG_TYPE.INFO),
new DiagHolder("Battery less than 50 percent.", DIAG_CODE.BATTERY_50, DIAG_TYPE.WARNING),
new DiagHolder("Battery less than 25 percent.", DIAG_CODE.BATTERY_25, DIAG_TYPE.WARNING),
new DiagHolder("Unexpected reset occured.", DIAG_CODE.UNEXPECTED_RESET, DIAG_TYPE.ERROR),
new DiagHolder("Unknown error.", DIAG_CODE.UNKNOWN_ERROR, DIAG_TYPE.ERROR),
};
public static class DiagHolder {
private String mmDescription;
private DIAG_CODE mmCode;
private DIAG_TYPE mmType;
DiagHolder(String description, DIAG_CODE code, DIAG_TYPE type)
{
this.mmDescription = description;
this.mmCode = code;
this.mmType = type;
}
}
Diagnostic(DIAG_CODE code, String timestamp, Context context) {
if (code.ordinal() >= 0 && code.ordinal() < Diags.length) {
this.mDiagHolder = Diags[code.ordinal()];
this.mTimestamp = timestamp;
this.mContext = context;
}
else {
this.mDiagHolder = new DiagHolder("Invalid diagnostic.", DIAG_CODE.UNKNOWN_ERROR, DIAG_TYPE.ERROR);
}
}
public String getDescription()
{
return this.mDiagHolder.mmDescription;
}
public DIAG_CODE getCode()
{
return this.mDiagHolder.mmCode;
}
public DIAG_TYPE getType()
{
return this.mDiagHolder.mmType;
}
public String getmTimestamp()
{
return mTimestamp;
}
}
如您在上面看到的,我已经注释掉了表的第一个诊断,并用访问R.string的行替换了它。 我通过将上下文从Activity传递到诊断程序来访问R,但是这不会起作用,因为它会在getResources()调用上生成NPE。
在ID下方,来自该活动的呼叫。 我为显示添加了虚拟诊断:
public class ViewDiagnosticsActivity extends AppCompatActivity {
...
private void buildDiagnosticList()
{
Diagnostic p = new Diagnostic(Diagnostic.DIAG_CODE.SYSTEM_ONLINE, "26OCT16 1439:10.76", this.getApplicationContext());
diagnostics.add(p);
}
}
有没有更好的方法可以做到这一点?
由于Diags
是一个静态字段,因此将在加载DiagHolder
类之后DiagHolder
对其进行初始化。 当时, context
可能尚未初始化,假设在上下文建立之前就已经加载了很多类。 因此,在静态初始化中使用上下文很危险。
在这种情况下,可以在DiagHolder
类中创建类似
public static void init(Context context);
并在其中初始化您的Diags
字段。
NullPointerException非常清楚:从未定义“上下文”。
请注意,您的“ DiagHolder”是静态内部类,因此可以在没有封闭类实例的情况下将其实例化,但是在这种情况下,它无权访问封闭类的实例成员(因为它们没有访问权限)。不存在!)
在这里,我已经声明了一个静态上下文,在访问DiagHolder []之前,必须初始化该静态上下文。
package com.example.prince.practice;
import android.content.Context;
public class Diagnostic {
public static Context context;
public enum DIAG_TYPE {
INFO, ERROR
}
public enum DIAG_CODE {
SYSTEM_ONLINE, SYSTEM_OFFLINE
}
public static class DiagHolder {
private String mmDescription;
private DIAG_CODE mmCode;
private DIAG_TYPE mmType;
DiagHolder(String description, DIAG_CODE code, DIAG_TYPE type) {
this.mmDescription = description;
this.mmCode = code;
this.mmType = type;
}
static final DiagHolder[] Diags = {
//new DiagHolder("System powered up.", DIAG_CODE.SYSTEM_ONLINE, DIAG_TYPE.INFO),
new DiagHolder(context.getResources().getString(R.string.SYSTEM_ONLIN), DIAG_CODE.SYSTEM_ONLINE, DIAG_TYPE.INFO)
};
}
}
从活动中使用,如下所示:
Diagnostic.context = this;
Diagnostic.DiagHolder[] holders = Diagnostic.DiagHolder.Diags;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.