Try-Catch: Is it OK to leave applications with handled exceptions? - android

I am still fairly new to programming, so there are some things I learn from observing but do not fully understand. The Try-Catch is one of these things. From what I have researched, the try statement allows me to define a block of code to be tested for errors, and the catch statement allows me to define a block of code to be executed if an error occurs in the try block.
I get that. And I have tried to use Try-Catch in situations where I was receiving exception errors that crashed my applications. The Try-Catch seemed to prevent (stop) the crashing. But here is my question, is it OK to have an application that constantly catches an exception error?
For example, I am working with EditText widget. I want the input values for the EditText to represent currency, so I applied android:inputType="numberDecimal". The issue I learned with this is that this attribute allows any number of values after the decimal. This is when I came up with an idea of updating the EditText programmically with the proper format, using something like DecimalFormat.
I am not posting my entire code, but here is the piece that I am curious about.
#Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
DecimalFormat format = new DecimalFormat("0.00");
if (etBill.getText().toString() != null &&
etBill.getText().toString().length() > 0) {
try {
doubleBill = Double.parseDouble(etBill.getText().toString());
strFormatted = format.format(doubleBill);
Log.d(TAG, "unformatted(" + doubleBill + ")" +
" // formatted(" + strFormatted + ")");
//etBill.setText("$" + strFormatted, TextView.BufferType.EDITABLE);
etBill.setText("$" + strFormatted);
} catch (NumberFormatException nfe) {
Log.e(TAG, "FloatingPointParser.parseDouble error");
}
} else {
// values in editText were deleted; hardcode value
doubleBill = 0.0;
strFormatted = format.format(doubleBill);
}
}
And here is the exception error I catch every single time I input a value into my EditText widget.
So my question is, is the Try-Catch a method for me to correct my errors? Is it OK to catch exception errors, such as this NumberFormapException through the life of an application running? Am I using this right? Thanks in advance!

NumberFormatException is a runtime exception and you are catching it correctly. However, instead of just printing something to let you know you have caught it, you should either handle it by re-running through your code or pass the exception up the stack. For example, if a user inputs a number and then this exception is caught, you could prompt them to re-enter a new number. If the number that is throwing this exception is not provided by a user, but by your code, then it indicates you have a logic error somewhere and should fix that to prevent this exception from being thrown in the first place.

In general the exception mechanism should be used for exceptional circumstances - something that usually shouldn't happen. If you have an exception that's being thrown every time you enter a value, that's sort of abusing the mechanism. Usually there's a better way that doesn't involve exceptions. In some cases though, the exception mechanism is the cleanest way of dealing with the situation.
Here's a quote from Effective Java: Programming Language Guide by Josh Bloch:
"Use exceptions only for exceptional conditions. That is, do not use exceptions for control flow, such as catching NoSuchElementException when calling Iterator.next() instead of first checking Iterator.hasNext()."

Exception handling is not only an art but the subject of much discussion/debate. I will try to address the broader points without incurring anyone's wrath.
There are two kinds of exceptions--fault exceptions and contingency exceptions. Fault exceptions are unrecoverable like being unable to connect to a web service that is supposed to be there for your app to function. You log those in your catch block and rethrow to let them bubble to some fault handler. Contingency exceptions are what you described with the number format issue--stuff you can recover from. In this case, you handle things completely in the catch block. You allow the app to recover by prompting for a new input, for example.
By the way, none of that is my own. That strategy comes from Barry Ruzek.
Then there is the issue where people dislike using exceptions for flow control--for good reason. In your case, that would mean using a regular expression in an if statement, for example, to test number format rather than using a potential exception-generating operation. You generally don't want to use exceptions for normal control flow, but you also need to be careful not to let ideology trump a simple solution. There is a balance you will learn with experience.
So you should recover from the exception in your catch block. Or use a different non-exceptional mechanism entirely to manage control flow.
Hope that helps.

Using Try catch in programing is fair enough. But handling errors is different issue. Try catch is just to way catch erronious conditions which can occur in ur program but u may wish to catch it or leave its up to you. Simple example is age is not allowed as floating point number but height is allowed both floating point and decimal number.

Related

Error handling in the onCreate() method of activity android

I am new to android development. In the overriden onCreate() method of my activity, I perform some operations. For ex. check if SharedPreference is already available and then route to other activity. How do I perform exception handling on this onCreate() method. Is it the right way to wrap the contents in a try catch and display the error dialog on exception?
If the exceptions are not handled properly, in my case the onCreate() method, the app crashes with message:
Unfortunately your application stopped working
On searching in the internet, I found that UncaughtExceptionHandler could be used to handle it. Any sample implementation and how to call it from all my activities would be helpful.
THat's the wrong way to go about it. Instead, go into your logcat. Read the stack trace of the exception. Figure out what you did wrong. Fix it. Just catching exceptions is a horrible practice unless you're catching a specific exception for a specific reason- its very unlikely your app is in a state where it can continue correctly. Don't be lazy, track down your bug and fix it.
With something like this you can catch a generic Exception in your onCreate() method:
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
try {
// do whatever you need
} catch (Exception e) {
e.printStackTrace();
}
}
Exception catching can be used with many goals. An interesting one is to catch particular expected exceptions to fix some problems (for example setting a generic value into a variable otherwise null after occurring an error).
The general purpose however is to avoid that an error causes a problem or in the worst case a crash of your application. Depending oh what kind of software you are developing, a crash may represents a little problem (like in an Android app), a very big one (like in airplane's softwares or power plants' softwares).
We can identify two kind of exceptions.
The first type are those exceptions specific to definite problems. They have to be declared into methods signature, so you are encouraged or obbligated to manage these exceptions and their relative problems. These exceptions represent an error that should probably occur during particular code execution, like a parsing error, or an input output error. For this type of problems we have particular exceptions, to catch and easily manage them (for example as previously said to init a variable with a default value after an error).
The second type of those exception represents instead some generic problems that can occur during program execution. They are a big and generic set and generally their probability of occurring is low. For this reason you are not obbligated to manage them. The main example of this type is the general Exception class.
So an catching an Exception is not the right approach to solve a bug, as suggested by Gabe Sechan.
Catching a generic Exception in the main() Java method can be a way, for example, to show a default human readable error to the user if nothing else is available.
Or could be a way to keep the failing of the current operation reducing crash probability.
Now, in Android we can't act directly on the main() method. onCreate() method is executed and exited so catching here a generic Exception has no much sense. Obviously it depends also on what you do in your onCreate() method and what you want to do if an error occurs. You could do some strange stuff (is very defined what you should do in the onCreate() method) and you could need to manage a big set of problems only showing an error, so it has more sense catch only a generic Exception than a lot of particular exceptions to make the same thing in each catch block.
If you want to achieve this goal (a message showed for all the errors occurred during onCreate() execution, made Activity by Activity) this is the right approach.
If instead what you want to achieve is to intercept all of the errors that are generated during all of your app execution, a good approach could be the UncaughtExceptionHandler, that act similarly to catch a generic Excepetion into a Java main() method. At this level an interesting approach is described here.
For more infos about exceptions you can read this and this.

Retrieve images from resource folder

I have an SQL database, from the DB I will be getting name string using that I need to show the icon in List.
To do this I followed two methods, one is:
int id= context.getResources().getIdentifier(path + i.getIcon(),null, null);
I found this method is not much efficient, so I followed some other technique i.e
try {
Class res = R.drawable.class;
Field field = res.getField(i.getIcon());
drawableId = field.getInt(null);
holder.ContactImage.setImageResource(drawableId);
}
catch (Exception e) {
Log.e("MyTag", "Failure to get drawable id.", e);
holder.ContactImage.setImageResource(R.drawable.ic_all_contacts_green);
}
Here the problem is, some time the icon name what I get from DB will not be present in Drawable folder, in that time I feel my UI is sluggish if I try to scroll, I tried using both technique mentioned above but I found no use.
How to overcome this problem, when icon is missing first method throws NULL and the second one shows exception, but why does it take too much time in doing that?
how to prevent the sluggishness in my UI, any efficient techniques?
To do this i followed two methods, one is
I would recommend:
context.getResources().getIdentifier(i.getIcon(), "drawable", context.getPackageName())
when icon is missing first method throws NULL and the second one shows exception
Do not ask for an icon that does not exist. Since you know, at compile time, exactly what icons do and do not exist, you are perfectly capable of not asking for icons that do not exist.
how to prevent the sluggishness in my UI
Use Traceview to find out exactly where your performance issue resides. Some will be in reflection -- whether you do it explicitly or (better) use getIdentifier(), there is still reflection going on. Ideally, you would cache the results of the getIdentifier() calls. But beyond that, Traceview will help pinpoint your difficulties.

avoiding a possible null in android

i have a situation where i may encounter a possible null, and i don't want my program to crash. it is only happening for a small % of users and i'm not entirely sure why, but i know the section of code that is doing it. basically the isAchieved() is a check that should return a boolean value, but in a few cases it is returning a null. this is part of a scoreloop library and i have a suspicion the bug might be with their code.
rather than getting a force close and exiting the program is there a way to check if this value is going to return a null and simply skip over this section of code if that is the case?
if (_achievements[ltc].isAchieved()) {
// Do stuff for 99.9% of users here, but skip if .isAchieved() would force close
}
boolean checker=false;
try{
checker=_achievements[ltc].isAchieved();
}
catch(NullPointerException e){
}
if (checker) {
//content
}
Did you think about doing that?.

android.util.Log when publishing - what can I do / not do

I've got a hell of a lot of Log.i Log.d Log.e in my code for a recent app I've done. I'm about to publish this app and I don't really want people seeing it when they plug there phone into adb, but I do want it there for my own debugging.
I was wanting to extend android.util.log and just have a boolean switch in there so I could just turn off the log when I publish and turn it on when developing but this class is final, am I missing a trick?
I don't really want to go through my code an remove all, true if worst comes to worst I could do a ctrl+h global replace Log for //Log but that does suck as an answer.
I also realise that Log.d is stripped out at runtime but it is still ran (losing a little performance) so not running this would be an added bonus.
Yeah so basically I'm looking for a way to toggle my debug on and off programatically, this can also allow me later on to make it a preference or something if people want to view it or help out and send it on.
What do you guys implement for this?
Thanks
As Octavian points out inserting a logging constant would be the best way to do this. Writing a new class for this that calls the original logging methods if debugging is enabled is not a good idea.
Good practice:
if (C.D) { Log.d(C.T, "your log text here " + foo + bar); }
Bad practice:
YourLog.d("your log text here " + foo + bar);
// and in YourLog.java's d() method:
... { if (debugging) Log.d(tag, text); }
The first solution is very fast if the constant D of class C is false. If you have complex string operations for creating your logging string they will not be executed if debugging is deactivated. The compiler can even remove these operations at compile time if D is false, which may result in zero runtime overhead. The second (bad) solution will always build the whole string and call a method, which is overhead you don't need.
In general the first solution would be best. And yes, I really call the class and members C, D and T (Constants/Debugging/Tag) - for performance reasons during typing. ;-)
obfuscate using Proguard as proguard has commands to use to filter it out when you write your proguard config file..nice and simple and it works
It is generally a good practice to not include them in your distribution code in any way since they will need to be processed which just leads to unnecessary battery drain.
You could set a boolean in your application somewhere to indicate development or release version of your code and have a lot of if blocks checking for the flag and executing your log code or not but this just leads to code bloat.
You should get rid of them once you no longer need them.

Exiting from Xml.parse when match is found

I'm using the Android SAX parser to search for entries in a rather large (6MB) XML file. I'm basically using a derivative of the code shown in listing 8 here. The question I have is how do I stop parsing once my match has been found? The code shown continues parsing through the end of the file but I want to stop before then. Is this possible or do I need to use something other than SAX (e.g. XmlPullParser?)
Generate an ArithmeticException and catch it !
if (condition) { int a=1; a/=0; }
...
try {
Xml.parse(this.getInputStream(), Xml.Encoding.UTF_8, root.getContentHandler());
}
catch (ArithmeticException e) {
return true;
}
That's awful but it works...
Well DiskCrasher,
Every Sax parser will work till the end generally, But if you still want to quit it while its in the middle of the work, you can always check condition and use the return statement.
But Far better way of selective parsing would be to use the XML PullParser, Coz this parser will in general work on the fly and give you data without loading the whole file. This way you can check condition and exit the loop anytime without even need to use large memory chunks...
Hope this is somehow helpful to you!!!
You can throw an exception when you get a match. The exception can capture the match info and will be propagated to the original parse() caller. Catch the exception and test whether it is one based on getting a match or a true parsing error and process accordingly.

Categories

Resources