开发者

How to restart android application from within application

开发者 https://www.devze.com 2023-01-28 06:36 出处:网络
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

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.


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


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.


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.


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


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.


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消