在实用程序中访问静态最终数组中的资源 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;