简体   繁体   English

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

[英]Accessing resources in a static final array in a utility class

I have a utility class for diagnostics (run time info, warning and error events) that defines the codes, severity levels, and human-readable messages for all possible diagnostics. 我有一个用于诊断(运行时信息,警告和错误事件)的实用程序类,它为所有可能的诊断定义代码,严重性级别和人类可读的消息。 There is also a DiagHolder that holds the information for the diag that was selected from the array and accessors for that data. 还有一个DiagHolder,用于保存从数组和该数据的访问器中选择的诊断信息。

I am refactoring away from hardcoded strings in the Java in order to use R.string for localization of the text that describes the diagnostic. 为了将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;
    }
}

As you can see above, I have commented out the first diag with the table and replaced it with a line that accesses R.string. 如您在上面看到的,我已经注释掉了表的第一个诊断,并用访问R.string的行替换了它。 I accessed R by passing context to the Diagnostic from the Activity.This will not work, however, since it generates an NPE on the getResources() call. 我通过将上下文从Activity传递到诊断程序来访问R,但是这不会起作用,因为它会在getResources()调用上生成NPE。

Below id the call from the activity. 在ID下方,来自该活动的呼叫。 I have added a dummy diagnostic for display: 我为显示添加了虚拟诊断:

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);
}

} }

Is there a better pattern for doing this? 有没有更好的方法可以做到这一点?

Since Diags is a static field, it will be initialized just after the DiagHolder class is loaded. 由于Diags是一个静态字段,因此将在加载DiagHolder类之后DiagHolder对其进行初始化。 At that time, context is probably not initialized yet, presuming that classes are loaded much before contexts are set up. 当时, context可能尚未初始化,假设在上下文建立之前就已经加载了很多类。 So, using a context in static initializations is dangerous. 因此,在静态初始化中使用上下文很危险。

In this case, in DiagHolder class you can make a method like 在这种情况下,可以在DiagHolder类中创建类似

public static void init(Context context);

and initialize your Diags field in it. 并在其中初始化您的Diags字段。

The NullPointerException is quite clear: ''context'' is never defined. NullPointerException非常清楚:从未定义“上下文”。

Pay attention that your ''DiagHolder'' is a static inner class, and therefore it can be instatiated without an instance of the enclosing class, but in that case it does not have access to instance members of the enclosing class (because they don't exist!) 请注意,您的“ DiagHolder”是静态内部类,因此可以在没有封闭类实例的情况下将其实例化,但是在这种情况下,它无权访问封闭类的实例成员(因为它们没有访问权限)。不存在!)

here, i have declared a static Context, before accessing that DiagHolder[],must initialize that static context. 在这里,我已经声明了一个静态上下文,在访问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)
    };
}

} }

use from activity, like this: 从活动中使用,如下所示:

    Diagnostic.context = this;
    Diagnostic.DiagHolder[] holders = Diagnostic.DiagHolder.Diags;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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