Reputation: 6043
I have a requirement to restart the application when the user changes a preference. Clearing the stack doesnt help me since this doesnt cancel the backend service calls. I want to kill the application process itself. I am using
Process.killProcess(Process.myPid());
and it works for me to kill the application. But what i need is to restart the application. Means kill the process and trigger a new process so the application start fresh once again.
Is there a way to do this?
Thanks in advance.
Upvotes: 8
Views: 14188
Reputation: 8371
If this is an enterprise project where you have control of the devices, you could easily install a second application that functions as a watchdog to the first. One of my clients uses such a watchdog application to handle things such as a nightly application reboot (for weird, non-technical reasons) and to check for and install self-served (non Play Store) application updates.
But if you really wanted to it from within your app, you can do the following (including your kill process above):
Process.killProcess(Process.myPid());
AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + 500 /* half a second*/,
PendingIntent.getActivity(this, 0, new Intent(this, this.getClass()),
Intent.FLAG_ACTIVITY_NEW_TASK));
Upvotes: 0
Reputation: 12858
If you really want to restart your activity including a kill of the current process, try following code. Place it in a HelperClass or where you need it.
public static void doRestart(Context c) {
try {
//check if the context is given
if (c != null) {
//fetch the packagemanager so we can get the default launch activity
// (you can replace this intent with any other activity if you want
PackageManager pm = c.getPackageManager();
//check if we got the PackageManager
if (pm != null) {
//create the intent with the default start activity for your application
Intent mStartActivity = pm.getLaunchIntentForPackage(
c.getPackageName()
);
if (mStartActivity != null) {
mStartActivity.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//create a pending intent so the application is restarted after System.exit(0) was called.
// We use an AlarmManager to call this intent in 100ms
int mPendingIntentId = 223344;
PendingIntent mPendingIntent = PendingIntent
.getActivity(c, mPendingIntentId, mStartActivity,
PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager mgr = (AlarmManager) c.getSystemService(Context.ALARM_SERVICE);
mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, mPendingIntent);
//kill the application
System.exit(0);
} else {
Log.e(TAG, "Was not able to restart application, mStartActivity null");
}
} else {
Log.e(TAG, "Was not able to restart application, PM null");
}
} else {
Log.e(TAG, "Was not able to restart application, Context null");
}
} catch (Exception ex) {
Log.e(TAG, "Was not able to restart application");
}
}
This will also reinitialize jni classes and all static instances.
Upvotes: 2
Reputation: 40347
This is not something which one should probably attempt to do outside of a testing environment.
That said, two ideas:
1) Set an alarm for some time in the very near future and then kill your process
2) Start up something else (perhaps a small native process or shell script) that will detect your death and restart you via an intent
You could also try firing off an intent to start yourself and then dying quickly, but this sounds like a potential race condition depending on implementation. If you grabbed the binder fd out of /proc and did evil things in native code, you might be able to fire off the intent in such a way that your application crashes on the return from the ioctl...
Upvotes: 5
Reputation: 24012
Since you are done with killing the process, to restart the application use this code:
Intent i = getBaseContext().getPackageManager().getLaunchIntentForPackage( getBaseContext().getPackageName() );
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
Upvotes: 2
Reputation: 116332
here's an idea:
have a service that has a different process than the one of your the rest of the components (activities , services,...) .
in order to restart the app , call this service and what it will do is to kill the processes of the other components of the app , and then send an intent to the activity that you wish to go to .
it's just an idea , since i've never tested it . please tell me if it works and update the question to include the answer if it really works.
Upvotes: 0
Reputation: 46579
Designing the OS so that an app could restart itself seems like a Very Bad Idea. The Android OS needs to be free to kill a process to free up memory -- if the app could restart itself suddenly the freed memory is used up again. I agree with Falmarri, you need to investigate why your app can't deal with a preference change on the fly.
Upvotes: 2
Reputation: 48567
Android is not designed to do this, and this is not a "requirement". This is an implementation. What exactly is the requirement? Why can't you design your app to handle preference changes without a restart? That seems like a very poor solution.
Upvotes: 4