Sometimes I just get to wondering and it leads me to Stupid Experiments.
Stupid Experiment One: Activity Constructor
Wondering: If I wrote a no-parameter Activity constructor, would it be called and, if so, would it be called on every call to onCreate?
Answer: Possibly!
Warning: Do not do this in production code!
Dumb Coding Experiment:
Given a static variable and a constructor in which the variable is incremented by one:
private static int init;
public ConfuseText() {
init++;
Log.d(TAG,"Constructor");
}
We decrement the static variable in onCreate:
@Override
public void onCreate(Bundle inState) {
super.onCreate(inState);
setContentView(R.layout.main);
init--;
Log.d(TAG,new Integer(init).toString());
Gives us the LogCat as:
Testing was repeated by calling init++ twice in the constructor and init-- only once in onCreate.
This verifies that the init variable is not simply being cleared on restart.
Not So Stupid Experiment Two: Exceptional Methods in a Thread
Wondering: If I run an exceptional method in a thread, how will I communicate back to the UI on exception?
Answer: Using Try Methods that wrap the exceptions into a BoolString class.
Given a BoolString class and exceptional method:
//a utility class to signal success or failure, return an error message, and return a useful String value
//see Try Out in C#
public final class BoolString {
public final boolean success;
public final String err;
public final String value;
public BoolString(boolean success, String err, String value){
this.success= success;
this.err= err;
this.value= value;
}
}
BoolString class that wraps an exception.
public String encrypt(String inString, String password) throws GeneralSecurityException {
boolean success= true;
String err="";
String outString="Encrypted"; // BoolString.value
byte[] iv;
try {...stuff here
}
catch (UnsupportedEncodingException e){err="Unable to convert key to byte array."; success= false;}
catch (InvalidKeyException e){err="Unable to generate KeySpec from key";success= false;}
catch (InvalidKeySpecException e){err="Invalid Key Specification";success= false;}
catch (IllegalArgumentException e){err="Illegal argument";success= false;}
catch (Exception e){err=e.getMessage();success= false;}
if (!success){throw new GeneralSecurityException(err);} // converted computerTalk to peopleTalk
return outString;
}
Exceptional Method.
We convert the exceptional method to a try method as in:
public BoolString tryEncrypt(String inString, String password) {
try {
String value= encrypt(inString, password);
return new BoolString(true,"",value);
}
catch (GeneralSecurityException e){
return new BoolString(false,e.getMessage(),"");
}
}
Try method that traps exceptions and wraps them into a BoolString object.
We create our inner class EncryptAsynch as in:
private class EncryptAsynch extends AsyncTask<String, Void, BoolString>{
protected void onPreExecute() {
resetProgress();
progress.show();
}
@Override
protected BoolString doInBackground(String...strings) { // <== DO NOT TOUCH THE UI VIEW HERE
// TODO Auto-generated method stub
String inString= strings[0];
String password= strings[1];
return model.tryEncrypt(inString,password); // <== return value String result is sent to onPostExecute
}
protected void onPostExecute(BoolString result){
progress.dismiss();
if (result.success){
isValidKey= true; // not needed?
editTextConfusedText.setText(result.value);
if (isShowCharCount) {
editTextPlainText.setText("Confused Char Count: "
+new Integer(result.value.length()).toString());
}
else {
editTextPlainText.setText("");
}
}
else {
editTextConfusedText.setText("");
editTextPassword.setError(result.err);
editTextPassword.requestFocus();
}
}
};
Where we refresh the progress dialog in the method resetProgress:
private void resetProgress() {
if (progress != null && progress.isShowing()){
progress.cancel();
}
progress= new ProgressDialog(this);
progress.setIndeterminate(true);
progress.setMessage("I am thinking.");
}
And launch our thread as in:
// threaded code
new EncryptAsynch().execute(inString,password);
Success.
On exception "Error".
Don't forget to implement:
protected void onPause() {
super.onPause();
if (progress != null){progress.cancel();}
}
Alternatively, consider Thread.UncaughtExceptionHandler.