At the beginning, I would like apologize for bad english.
There is my problem:
I have a service in android which runs on background when is activity running. (This service synchronize user data with server with specified time intervals).
public class CService extends Service
{
private Boolean isDestroyed;
@Override
public int onStartCommand (Intent intent, int flags, int startId)
{
if (intent != null)
{
new Thread(new Runnable()
{
//run new thread to disable flush memory for android and destroy this service
@Override
public void run ()
{
this.isDestroyed = Boolean.FALSE
while(!this.isDestroyed)
{
//loop until service isn't destroyed
}
}
}).start();
}
return Service.START_NOT_STICKY;
}
@Override
public void onDestroy ()
{
//THIS ISNT CALLED FROM uncaughtException IN ACTIVITY BUT from onDestroy method is this called.
//when is service destroyed then onDestroy is called and loop finish
this.isDestroyed = Boolean.TRUE;
}
}
And is started from activity in onCreateMethod. This activity implements Thread.UncaughtExceptionHandler and register in onCreate method to catch all unexpected exceptions in activity. When something in activity throw exception method uncaughtException is called and and service should stop with stopService(serviceIntent); But onDestoy in service isn't called. But when is onDestroy method in activity called (user push then back button) service is stopped succesfully and onDestoroy in CService is called.
public class CActivity extends Activity implements Thread.UncaughtExceptionHandler
{
private Thread.UncaughtExceptionHandler defaultUEH;
@Override
protected void onCreate (Bundle savedInstanceState)
{
this.defaultUEH = Thread.getDefaultUncaughtExceptionHandler();
// create intent for service
Intent serviceIntent = new Intent(this, CService.class);
// run service
startService(serviceIntent);
//set default handler when application crash
Thread.setDefaultUncaughtExceptionHandler(this);
super.onCreate(savedInstanceState);
}
@Override
public void uncaughtException (Thread thread, Throwable ex)
{
//THIS DOESN'T WORK
//when global exception in activity is throws then this method is called.
Intent serviceIntent = new Intent(this, CService.class);
//method to service stop is called. BUT THIS METHOD DON'T CALL onDestroy in CService
stopService(serviceIntent);
defaultUEH.uncaughtException(thread, ex);
}
@Override
public void onDestroy ()
{
//this work fine
Intent serviceIntent = new Intent(this, CService.class);
stopService(serviceIntent);
super.onDestroy();
}
}
I need stop background service when activity crashes. Bacause when android close activity and start previous activity in stack (Which is login screen) no user is now logged.
Thanks for suggestions.
Try this
Thread.currentThread().setUncaughtExceptionHandler(this);
UPD
this is default android exception handler
private static class UncaughtHandler implements Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
try {
// Don't re-enter -- avoid infinite loops if crash-reporting crashes.
if (mCrashing) return;
mCrashing = true;
if (mApplicationObject == null) {
Slog.e(TAG, "*** FATAL EXCEPTION IN SYSTEM PROCESS: " + t.getName(), e);
} else {
Slog.e(TAG, "FATAL EXCEPTION: " + t.getName(), e);
}
// Bring up crash dialog, wait for it to be dismissed
ActivityManagerNative.getDefault().handleApplicationCrash(
mApplicationObject, new ApplicationErrorReport.CrashInfo(e));
} catch (Throwable t2) {
try {
Slog.e(TAG, "Error reporting crash", t2);
} catch (Throwable t3) {
// Even Slog.e() fails! Oh well.
}
} finally {
// Try everything to make sure this process goes away.
Process.killProcess(Process.myPid());
System.exit(10);
}
}
}
I believe you don't get the onDestroy() call, because the default android exception handler simply destroys entire process System.exit(). You can try not to call defaultUEH.uncaughtException(thread, ex); or call it later after(if) your service is destoryed.