How do I programmatically “restart” an Android app?

后端 未结 26 1974
小鲜肉
小鲜肉 2020-11-22 12:42

Firstly, I know that one should not really kill/restart an application on Android. In my use case, I want to factory-reset my application in a specific case where a server s

相关标签:
26条回答
  • 2020-11-22 13:04

    With the Process Phoenix library. The Activity you want to relaunch is named "A".

    Java flavor

    // Java
    public void restart(){
        ProcessPhoenix.triggerRebirth(context);
    }
    

    Kotlin flavor

    // kotlin
    fun restart() {
        ProcessPhoenix.triggerRebirth(context)
    }
    
    0 讨论(0)
  • 2020-11-22 13:05

    My best way to restart application is to use finishAffinity();
    Since, finishAffinity(); can be used on JELLY BEAN versions only, so we can use ActivityCompat.finishAffinity(YourCurrentActivity.this); for lower versions.

    Then use Intent to launch first activity, so the code will look like this:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        finishAffinity();
        Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
        startActivity(intent);
    } else {
        ActivityCompat.finishAffinity(YourCurrentActivity.this);
        Intent intent = new Intent(getApplicationContext(), YourFirstActivity.class);
        startActivity(intent);
    }
    

    Hope it helps.

    0 讨论(0)
  • 2020-11-22 13:06

    try this:

    Intent intent = getPackageManager().getLaunchIntentForPackage(getPackageName());
    intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
    startActivity(intent);
    
    0 讨论(0)
  • 2020-11-22 13:07

    IntentCompat.makeMainSelectorActivity - Last tested on 11/2020

    The app will be restored with the launcher activity and the old process will be killed.

    Works from Api 15.

    public static void restart(Context context){
        Intent mainIntent = IntentCompat.makeMainSelectorActivity(Intent.ACTION_MAIN, Intent.CATEGORY_LAUNCHER);
        mainIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.getApplicationContext().startActivity(mainIntent);
        System.exit(0);
    }
    
    0 讨论(0)
  • 2020-11-22 13:07

    There is a really nice trick. My problem was that some really old C++ jni library leaked resources. At some point, it stopped functioning. The user tried to exit the app and launch it again -- with no result, because finishing an activity is not the same as finishing (or killing) the process. (By the way, the user could go to the list of the running applications and stop it from there -- this would work, but the users just do not know how to terminate applications.)

    If you want to observe the effect of this feature, add a static variable to your activity and increment it each, say, button press. If you exit the application activity and then invoke the application again, this static variable will keep its value. (If the application really was exited, the variable would be assigned the initial value.)

    (And I have to comment on why I did not want to fix the bug instead. The library was written decades ago and leaked resources ever since. The management believes it always worked. The cost of providing a fix instead of a workaround... I think, you get the idea.)

    Now, how could I reset a jni shared (a.k.a. dynamic, .so) library to the initial state? I chose to restart application as a new process.

    The trick is that System.exit() closes the current activity and Android recreates the application with one activity less.

    So the code is:

    /** This activity shows nothing; instead, it restarts the android process */
    public class MagicAppRestart extends Activity {
        // Do not forget to add it to AndroidManifest.xml
        // <activity android:name="your.package.name.MagicAppRestart"/>
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            System.exit(0);
        }
        public static void doRestart(Activity anyActivity) {
            anyActivity.startActivity(new Intent(anyActivity.getApplicationContext(), MagicAppRestart.class));
        }
    }
    

    The calling activity just executes the code MagicAppRestart.doRestart(this);, the calling activity's onPause() is executed, and then the process is re-created. And do not forget to mention this activity in AndroidManifest.xml

    The advantage of this method is that there is no delays.

    UPD: it worked in Android 2.x, but in Android 4 something has changed.

    0 讨论(0)
  • 2020-11-22 13:07

    The best way to fully restart an app is to relaunch it, not just to jump to an activity with FLAG_ACTIVITY_CLEAR_TOP and FLAG_ACTIVITY_NEW_TASK. So my solution is to do it from your app or even from another app, the only condition is to know the app package name (example: 'com.example.myProject')

     public static void forceRunApp(Context context, String packageApp){
        Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageApp);
        launchIntent.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS | Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(launchIntent);
    }
    

    Example of usage restart or launch appA from appB:

    forceRunApp(mContext, "com.example.myProject.appA");
    

    You can check if the app is running:

     public static boolean isAppRunning(Context context, String packageApp){
        ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List<ActivityManager.RunningAppProcessInfo> procInfos = activityManager.getRunningAppProcesses();
        for (int i = 0; i < procInfos.size(); i++) {
            if (procInfos.get(i).processName.equals(packageApp)) {
               return true;
            }
        }
        return false;
    }
    

    Note: I know this answer is a bit out of topic, but it can be really helpful for somebody.

    0 讨论(0)
提交回复
热议问题