I'm developing a videogame in Android which closes unexpectedly and randomly. The case is I have the following code envolving my game loop:
try {
//game loop
}
catch(Exception e)
{
//...
}
catch(OutOfMemoryError e)
{
//...
}
For some reason, the app is not entering any of those catchs. I thought it was a memory problem, but with the 'OutOfMemoryError' it should be covered right? Or this just covers when we demand a lot of memory all the sudden?
I was wondering if there is any catch condition to capture ALL the possible situations because this is driving me crazy...
Without looking at any code. I would posit that perhaps you have an endless loop in your gameloop and it is causing the app to be unresponsive. Which is causing the OS to handle any exceptions or issues raised.
Related
I would like to know your ways to handle different kinds of errors (like http exceptions, no internet connection exceptions etc) in retrofit Rx onError without using instanceof like it's proposed here: How to handle network errors in Retrofit 2 with RxJava or here: Handle errors in Retrofit 2 RX
In kotlin I will simply make some extension functions for each kind of throwable to do whatever I want.
But I am forced to use Java in the project. Any nice suggestions?
is the approach to build some kind of error handler like this:
public interface ErrorHandler {
void handleError(Exception e);
void handleError(HttpException e);
void handleError(NullPointerException npe);
}
good? I know it is not because every time i need to handle another specific error I am forced to change interface, so it is violation of Open Close Principle. But I can't figure out any solution .
cheers
Wojtek
The compiler determines which method to call, rather than the VM. So the class you've described won't solve the problem unless you check instanceof first and cast the paramter to the correct type. Otherwise you're going to get handleError(Exception e) every time.
But I wanted to create an answer not for that reason, but to argue that having only one error handler is actually preferable in many cases, not a liability. Oftentimes in java we end up in awful situations like this:
catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("No such algorithm: RSA?", e);
}
catch (NoSuchProviderException e) {
throw new IllegalStateException("No such provider: " + ANDROID_KEYSTORE_ID, e);
}
catch (InvalidAlgorithmParameterException e) {
throw new IllegalStateException("Bug setting up encryption key for user credentials: ", e);
}
catch (KeyStoreException e) {
throw new IllegalStateException("Bug setting up encryption key for user credentials: ", e);
}
catch (IOException e) {
Log.w(TAG, "Exception setting up keystore for user creds. They won't be stored.", e);
}
catch (CertificateException e) {
Log.w(TAG, "Exception setting up keystore for user creds. They won't be stored.", e);
}
Having only one error handler gives us the ability to lump many types of exceptions together. You can see in this code, there are exceptions that should never be thrown, exceptions that can really only be the result of a bug in the code, and legitimate exceptional states that we need to handle. I find this messy, and would prefer to say:
if (e instanceof NoSuchAlgorithmException || e instanceof NoSuchProviderException) {
Log.wtf(TAG, "What the heck is this?", e);
throw new IllegalStateException("This is some kind of weird bug", e);
}
else if (e instanceof IOException || e instanceof CertificateException) {
// This can happen sometimes, track event in analytics and perhaps
// try some alternative means of credential storage.
}
else {
// At least here the app won't crash if some unexpected exception occurs,
// since we're trapping everything.
}
I don't think it's such a bad thing to be able to lump unexpected failures together and handle them in a more user friendly way than crashing the app. Even if it's just a bug, better to track it in your analytics framework behind the scenes than bomb the user out of the app. So many crashes in Android apps are actually completely recoverable, but we don't go around catching Throwable in every try/catch statement because it's a lot of extra code.
The proper OOP way to avoid chained ifs or catches is polymorphism. You can define several custom exception classes exposing common interface that is enough for a single handler to process.
Suppose you need to divide errors in two groups: recoverable and not recoverable. Then your base exception class (or interface) shall have abstract method isRecoverable() that you override in each subclass. Then there will be only one if in your handler: if (e.isRecoverable()) { ... } else { ... }.
The downside is that you have to wrap all standard exceptions into your custom ones at places where they are thrown (you have to catch them).
The right choice will greatly depend on your task, though.
Let's say I have async tasks that when finished, lock the vibrator and send it a pattern. In a nutshell, that's the kind of code I'm dealing with:
lock(vib);
vib.vibrate(pattern);
release(vib);
return;
The problem is, the vibration starts and just immediately stops due to the task's returning and I could use some help in changing that.
I have tried
lock(vib);
long duration = getDuration(pattern);
vib.vibrate(pattern);
synchronized(this){
try {
wait(duration);
} catch (InterruptedException e) {
...
}
}
release(vib);
return;
but that doesn't seem to actually do anything.
Since I have not found a way to determine whether or not the phone is currently vibrating, any suggestions on how I should best resolve the issue?
Android keeps on reporting crashes from users which I can't reproduce on my phone.
I can find the lines which seem to be incorrect:
cursor.moveToFirst();
elechs=cursor.getString(2);
elecls=cursor.getString(3);
gass=cursor.getString(4);
waters=cursor.getString(5);
cursor.close();
if (elechs.length()!=0){
elechdb=Double.valueOf(elechs);
}
else {
elechdb=0.0;
}
if (elecls.length()!=0){
elecldb=Double.valueOf(elecls);}
else {
elecldb=0.0;
}
if (gass.length()!=0){
gasdb=Double.valueOf(gass);
}
else {
gasdb=0.0;
}
if (waters.length()!=0){
waterdb=Double.valueOf(waters);
}
else {
waterdb=0.0;
}
elecldb=Double.valueOf(elecls);
gasdb=Double.valueOf(gass);
waterdb=Double.valueOf(waters);
If I look at the code, it doesn't make any sense.
I think I forgot to delete the last three lines. First I check the string. If the string is empty it will store the value as zero.
The incorrect last three lines will also try to make a double if the cell is empty. This cause a lot of crashes. However not on my machine.
I believe that it shouldn't be possible to make a of an empty cell.
Does anyone know why this error doesn't crash my phone?
Your best solution is probably just to remove the problematic lines that shouldn't be there anyway, preferably add actual error handling around calls to Double.valueOf() in case the input is completely malformed (there may be inconsistent behaviour if the cell is empty, but if it says "hello world", everything will crash), and release an update.
Since the users are getting NumberFormatException, you should catch the exception and perform appropriate action when it happens.
if (elechs.length()!=0) {
try {
elechdb=Double.valueOf(elechs);
} catch (NumberFormatException e) {
// Perform error handling
}
}
If the users are getting NullPointerException, you should check if the strings are null before checking for their lengths.
If the data is put in by the user, you should do both of the above to avoid future problems.
I just released a new version of my application to the Android market, and my new version has a GLSurfaceView in the activity. Even though I'm not doing anything fancy, I have a large user base, there's a lot of substandard Android phones out there, and I'm invariably getting exceptions in GLThread.run().
What is the recommended way to catch/handle these exceptions without crashing the entire app? Ideally I'd like to be able to catch the error, remove the surface view from the activity and switch off the component that uses OpenGL. I did a bit of searching but mostly found exception reports for Firefox on Android and stuff like that. :)
I'm thinking of just using an uncaught exception handler, switching a shared preferences flag to false, and letting it crash; the next run I won't try to add that GLSurfaceView.
I ended up working around the problem with the following code:
final UncaughtExceptionHandler defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread thread, Throwable ex) {
if (thread.getName().startsWith("GLThread")) {
disableOpenGLStuff();
}
// You could wrap this in an else, but I'm not sure how good of an idea it is to leave the application running when a thread has crashed.
defaultHandler.uncaughtException(thread, ex);
});
02-07 10:49:45.558: E/dalvikvm-gc(7184): Could not create 2617344-byte ashmem mark stack: Too many open files
While I was playing the game and after some time the game forced closed showing the above error in Log Cat. Is there any solution for this?? and what could be its cause??
The cause is that your code is not closing files and the system is running out of file handles. You should always use files using a coding pattern that ensures that all streams are closed when no longer needed. Here's a typical pattern:
InputStream is = null;
try {
is = new FileInputStream(myFile);
// read stuff from is
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
Log.w(LOG_TAG, "Exception raised when closing file", e);
}
}
}
The outer try could also have a catch clause. The reason for the try/catch in the finally clause is to prevent an exception in closing the file from suppressing any exception raised in the outer try block.
Writing to files tends to be less of a problem because programmers usually take care to close the file to ensure that the data reaches the file. However, a similar pattern should be followed there: never let an exception prevent the closing of a file.