8

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.

1
  • I'm wondering if this is needed for testing purposes or if its something that you need to do in a live app? Commented Dec 5, 2010 at 16:36

7 Answers 7

5

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...

Sign up to request clarification or add additional context in comments.

Comments

4

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.

4 Comments

I have couple of testing environments and they have their specific properties for establishing connection with environment specific servers. So when we switch between environments I need to restart the whole application with new properties.
So is this for testing code or production code? If it's for testing, then sure go ahead and kill the process. You can then probably restart it in your testing code.
I gave up the idea of restarting the application instead I am resetting my HTTP connection to reestablish a new one since the earlier was timing out if the device is idle for more than 20 mins. Thats why we wanted to restart the app to reestablish the new connection to connect to our servers.
how do you reset the connection ?
2

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.

3 Comments

I gave detailed requirement to Falmarri. Can you please look that up and see if there is a way we can do it. But anyways I need the application to be restarted from within the application. This is for sure and this req cant be changed.
So this is essentially a method of speeding up the QA process?
You never know what requirements for an application could be. For example, a tablet on a shop display is playing a movie non-stop. When a customer manages to reach Android home screen, the app should immediately restart itself.
2

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);

Comments

2

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.

Comments

0

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.

Comments

0

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.