Issue
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.
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.
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. 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.
Below id the call from the activity. 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?
Solution
Since Diags
is a static field, it will be initialized just after the DiagHolder
class is loaded. At that time, context
is probably not initialized yet, presuming that classes are loaded much before contexts are set up. So, using a context in static initializations is dangerous.
In this case, in DiagHolder
class you can make a method like
public static void init(Context context);
and initialize your Diags
field in it.
Answered By - nandsito
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.