在实用程序中访问静态最终数组中的资源 class
Accessing resources in a static final array in a utility class
我有一个用于诊断(运行 时间信息、警告和错误事件)的实用程序 class,它为所有可能的诊断定义了代码、严重级别和人类可读的消息。还有一个 DiagHolder,用于保存从数组中选择的诊断信息和该数据的访问器。
我正在重构 Java 中的硬编码字符串,以便使用 R.string 对描述诊断的文本进行本地化。
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;
}
}
正如您在上面看到的,我用 table 注释掉了第一个诊断,并将其替换为访问 R.string 的行。但是,我通过将上下文从 Activity.This 传递给诊断来访问 R 将不起作用,因为它会在 getResources() 调用上生成 NPE。
下面是来自 activity 的呼叫。我为显示添加了一个虚拟诊断:
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);
}
}
有更好的模式吗?
NullPointerException 非常清楚:“'context'”从未定义。
注意你的''DiagHolder''是一个静态内部class,因此它可以在没有封闭class的实例的情况下被实例化,但在那种情况下它确实如此无法访问封闭 class 的实例成员(因为它们不存在!)
由于Diags
是一个静态字段,它会在DiagHolder
class加载后立即初始化。那时,context
可能还没有初始化,假设 classes 在设置上下文之前加载了很多。因此,在静态初始化中使用上下文是危险的。
在这种情况下,在 DiagHolder
class 中,您可以创建一个类似
的方法
public static void init(Context context);
并初始化其中的 Diags
字段。
在这里,我已经声明了一个静态上下文,在访问那个 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)
};
}
}
使用 activity,像这样:
Diagnostic.context = this;
Diagnostic.DiagHolder[] holders = Diagnostic.DiagHolder.Diags;
我有一个用于诊断(运行 时间信息、警告和错误事件)的实用程序 class,它为所有可能的诊断定义了代码、严重级别和人类可读的消息。还有一个 DiagHolder,用于保存从数组中选择的诊断信息和该数据的访问器。
我正在重构 Java 中的硬编码字符串,以便使用 R.string 对描述诊断的文本进行本地化。
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;
}
}
正如您在上面看到的,我用 table 注释掉了第一个诊断,并将其替换为访问 R.string 的行。但是,我通过将上下文从 Activity.This 传递给诊断来访问 R 将不起作用,因为它会在 getResources() 调用上生成 NPE。
下面是来自 activity 的呼叫。我为显示添加了一个虚拟诊断:
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);
}
}
有更好的模式吗?
NullPointerException 非常清楚:“'context'”从未定义。
注意你的''DiagHolder''是一个静态内部class,因此它可以在没有封闭class的实例的情况下被实例化,但在那种情况下它确实如此无法访问封闭 class 的实例成员(因为它们不存在!)
由于Diags
是一个静态字段,它会在DiagHolder
class加载后立即初始化。那时,context
可能还没有初始化,假设 classes 在设置上下文之前加载了很多。因此,在静态初始化中使用上下文是危险的。
在这种情况下,在 DiagHolder
class 中,您可以创建一个类似
public static void init(Context context);
并初始化其中的 Diags
字段。
在这里,我已经声明了一个静态上下文,在访问那个 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)
};
}
}
使用 activity,像这样:
Diagnostic.context = this;
Diagnostic.DiagHolder[] holders = Diagnostic.DiagHolder.Diags;