繁体   English   中英

在实用程序类中访问静态最终数组中的资源

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM