I am developing an app with quite a few threads, it often crashes so far, whenever I load the new version from eclipse, it seems to create a new process.
I cannot seem to find a way to kill the old processes, they do not apear in the running apps.
I can see that I have multiple processes related to my app in the process list ("ps" command).
Is there a way to make sure the app process actually dies on crash?
have you tried this android.os.Process.killProcess(android.os.Process.myPid()); it can kill your process
You can kill your app's process by:
System.exit(1);
It order to know when your app crashes (exception that's not being caught) you'll need to define:
Thread.setDefaultUncaughtExceptionHandler(new CustomUncaughtExceptionHandler());
In your main Thread.
CustomUncaughtExceptionHandler is:
public class CustomUncaughtExceptionHandler implements UncaughtExceptionHandler
{
private UncaughtExceptionHandler defaultUEH;
public CustomUncaughtExceptionHandler()
{
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
public void uncaughtException(Thread t, Throwable e)
{
// Put system.exit here
if (defaultUEH != null)
{
defaultUEH.uncaughtException(t, e);
}
else
{
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
defaultUEH.uncaughtException(t, e);
}
}
}
Related
I want to send a firebase crash report for every uncaught exception in my app but I also want to Android system to show the "App has stopped responding" dialog. How do I go about this?? I already have an UncaughtException handler that sends the firebase crash report. My issue now is letting Android handle the rest of the process.
The uncaught exception can be delegated back to system by storing the old exception handler and passing uncaught exceptions to it.
First create an Application class as below:
public class Controller extends Application {
private static Thread.UncaughtExceptionHandler defaultHandler;
#Override
public void onCreate() {
super.onCreate();
if (defaultHandler == null) {
defaultHandler = Thread.getDefaultUncaughtExceptionHandler();
}
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
#Override
public void uncaughtException(Thread t, Throwable e) {
FirebaseCrash.report(e); //or whatever
defaultHandler.uncaughtException(t, e); //this will show crash dialog.
}
});
}
}
Then use this class as application in the manifest as:
<application
android:name=".Controller"
... />
I know there are already good tools available like crashlytics, but i have a requirment and i can't use these tools.
All i need to is to save the crash log before application exists, and that without disturbing the normal flow, and using any 3rd party library
I have implemented this, but it has disturb the normal flow of android crashing. I want to save the log, but don't want to disturb the normal crashing flow.
This is what i am doing to save the crash log.
public void registerCrash(){
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
public void handleUncaughtException (Thread thread, Throwable e)
{
thread.getStackTrace();
savePreferenceData(e.toString());
System.exit(0);
}
public void savePreferenceData(String data) {
SharedPreferences sharedPreferences= context.getSharedPreferences(LOG_DATA, Context.MODE_PRIVATE);
SharedPreferences.Editor prefsEditor = sharedPreferences.edit();
prefsEditor.putString(STACK_TRACE, data);
prefsEditor.apply();
}
The problem is that, It restarts the application, without giving the default Alert dialog to user. Unfortunately App has stopped.
Kindly guide me how to save crash log witout disturbing the normal crash mechanisim
Before setting the UncaughtExceptionHandler, keep track of the one that was set before and simply call it from your own handler after you are done:
private Thread.UncaughtExceptionHandler defaultExceptionHandler;
public void registerCrash(){
defaultExceptionHandler = Thread.getDefaultUncaughtExceptionHandler();
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler(){
#Override
public void uncaughtException (Thread thread, Throwable e){
handleUncaughtException (thread, e);
if(defaultExceptionHandler != null){
defaultExceptionHandler.uncaughtException(thread, e);
}
}
});
}
I want to make some classes that catch runtime errors on android and offers the user the option to restore the last saved instance state of the app.
I was thinking of extending the Activity and Fragment classes and implement something that saves their state. In the meantime, another class handles every start of an activity or fragment, putting them in a stack.
I want to catch every possible exception in the app, hopefully making errors less bothersome for the user.
Any advice on how I should handle this?
How would this error checking influence the performance of an app?
It's not a good solution and i don't know if it's useful for you, but you can caught exceptions in Application Class.
public class MyApplication extends Application
{
public void onCreate ()
{
// Setup handler for uncaught exceptions.
Thread.setDefaultUncaughtExceptionHandler (new Thread.UncaughtExceptionHandler()
{
#Override
public void uncaughtException (Thread thread, Throwable e)
{
handleUncaughtException (thread, e);
}
});
}
public void handleUncaughtException (Thread thread, Throwable e)
{
e.printStackTrace();
// do what ever you want.
}
}
You can use try catch blocks to catch runtime errors. If you use try catch efficiently with throws your app won't crash in first place hence no need to maintain stack of activities. btw maintaining stacks of previous activity in neither memory efficient nor advisable.
I have a Service like this (this is not the actual Service, it's just for describing my problem).
public class UploadService {
private BlockingQueue<UploadData> queue = null;
private UploadInfoReceiver receiver = null;
public void onStart(...) {
queue = new LinkedBlockingQueue<UploadData>();
(new Processor()).start();
// creating and reigtering receiver
}
public void onDestroy() {
queue.add(new ServiceDestroyedData());
// unregistering the receiver
}
private class Processor extends Thread() {
public void run() {
while (true) {
UploadData data = queue.take();
if (data instanceof ServiceDestroyedData) {
return;
}
// processing data
}
}
}
private class UploadInfoReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
queue.add(new UploadData(/* getting data from intent */));
}
}
}
And my problem is that if I do something like this in my App:
if (!isUploadServiceRunning()) {
// start the Service
}
Then it starts the Service, but when I move my App to the background and open task manager (android 4.2.2), and kill the app, Android restart my Service, and I can see that it creates a whole new instance of it, and I can see that onDestroy never gets called for the previous Service instance. And I also can see that the instance of the previous Processor Thread is no longer running. How can this be? If onDestroy never gets called how does Android know that it should stop my Thread?
Thanks for your answers.
Android will kill off anything that it finds that is attached to your apps classloader when you select force stop from the menu. Think kill -9 on Linux. There will be no nice callbacks to any onDestroy methods, the system will just end everything.
Now for your service:
while(true) should really NEVER be used. It will instantly kill the battery and will not do any work 99% of the time anyway.
You area already using a receiver, you can just put your while logic into there and once the upload is done call the next upload and so on. There is absolutely no need for the loop.
I added an exceptionhandler for unhandled exceptions, to know that the app has crashed on the next app start:
#Override
public void uncaughtException(Thread thread, Throwable ex) {
SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getBaseContext());
SharedPreferences.Editor editor = preferences.edit();
editor.putString("crashed", "yes");
editor.commit();
}
I added the handler via:
Thread.setDefaultUncaughtExceptionHandler(this);
Now the thing is: since I added the handler, the app behaves differently on error:
Before I added the handler I got a popup telling me that the app has crashed.
Now, after adding the handler the app just freezes, and after a while android shows me a popup telling me that the app does not respond anymore and whether I want to wait any longer. This is not good IMO. Any hints, how to properly exit after an application crash?
you can save the original exception handler , so that you can call it after you are done with doing your own custom operations on the unhandled exception . something like this:
//Inside UncaughtExceptionHandler.java:
…
private UncaughtExceptionHandler defaultUEH;
public DefaultExceptionHandler()
{
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
}
#Override
public void uncaughtException(Thread t, Throwable e)
{
//do anything you wish about the Throwable e :getStackTrace(),getCause(),getClass()...
//call the original uncaught exception handler:
defaultUEH.uncaughtException(t, e);
}
I suggest that you integrate your logic with ACRA, so that it can handle the issues of crash reporting and cleanup.