I want to handle unhandled exception in my app without any third-party libraries.
So i write a code.
Activity :
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Thread.setDefaultUncaughtExceptionHandler(new ReportHelper(this));
throw new NullPointerException();
}
My crash handler :
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.MessageQueue;
import android.widget.Toast;
/**
* Created by S-Shustikov on 08.06.14.
*/
public class ReportHelper implements Thread.UncaughtExceptionHandler {
private final AlertDialog dialog;
private Context context;
public ReportHelper(Context context) {
this.context = context;
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Application was stopped...")
.setPositiveButton("Report to developer about this problem.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Not worked!
dialog.dismiss();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}
});
dialog = builder.create();
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
showToastInThread("OOPS!");
}
public void showToastInThread(final String str){
new Thread() {
@Override
public void run() {
Looper.prepare();
Toast.makeText(context, "OOPS! Application crashed", Toast.LENGTH_SHORT).show();
if(!dialog.isShowing())
dialog.show();
Looper.loop();
}
}.start();
}
}
When i start app as you see i throwed NullPointerException. Toast
in my handling logic was showed, and dialog was showed too. BUT! Dialog clicks was not handling correct. I mean logic in onClick
method was not worked. What the problem and how i can fix that?
In my case, I moved AlertDialog.Builder
in thread run function like this:
public void showToastInThread(final String str){
new Thread() {
@Override
public void run() {
Looper.prepare();
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage("Application was stopped...")
.setPositiveButton("Report to developer about this problem.", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
})
.setNegativeButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
// Not worked!
dialog.dismiss();
System.exit(0);
android.os.Process.killProcess(android.os.Process.myPid());
}
});
dialog = builder.create();
Toast.makeText(context, "OOPS! Application crashed", Toast.LENGTH_SHORT).show();
if(!dialog.isShowing())
dialog.show();
Looper.loop();
}
}.start();
}
and all thing work perfectly.
Hope this help you.
According this post, the state of the application is unknown, when setDefaultUncaughtExceptionHandler
is called. This means that your onClick listeners may not be active anymore.
Why not use this method:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
setContentView(R.layout.main);
Thread.setDefaultUncaughtExceptionHandler(new ReportHelper(this));
throw new NullPointerException();
} catch (NullPointerException e) {
new ReportHelper(this);
}
}
and remove ReportHelper implementing the Thread.UncaughtExceptionHandler
interface.
Your method of not explicitly catching exceptions can be seen as an anti-pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With