How to restart an Activity automatically after it

2019-02-20 04:46发布

问题:

Is there a way for me to create a service to track my activity class and restart it after a crash? Note that i CANNOT use uncaughthandlers thread method to restart my app. My app is supposed to crash, don't worry about that part. My app is something simple, like this

private class AudioRenderer extends Activity {

private MediaPlayer AudioRenderer(String filePath) {
File location = new File(filePath);
        Uri path = Uri.fromFile(location);
  mp= MediaPlayer.create(this, path); 

}
return mp


}

Once this crashes, the service listening in the background will restart my app automatically. Anybody knows how this is possible? Thanks!

回答1:

You can do that, yes, as explained below. But if such techniques may make sense for experiments, they are definitely not suitable for production. That would be awfully ugly and unefficient.

This said, here is a way to go:

  • Make your Service sticky or redelivered to ensure it will always be running after having been started once and not explicitely stopped.

  • in your Activity class, statically store WeakReferences pointing to all its running instances and provide a way to statically check whether at least one of them is currently allocated:

    public class MyActivity extends Activity {
        private static ArrayList<WeakReference<MyActivity >> sMyInstances = new ArrayList<WeakReference<MyActivity >>();
    
        public MyActivity() {
            sMyInstances.add(new WeakReference<MyActivity >(this));            
        }
    
        private static int nbInstances() {
            int ret = 0;
            final int size = sMyInstances.size();
    
            for (int ctr = 0; ctr < size; ++ctr) {
                if (sMyInstances.get(ctr).get() != null) {
                    ret++; 
                }
            }
    
            return ret;
        }
    }
    

(WeakReference are references to objects that do not prevent these objects to be garbage-collected, more details here)

  • Then, from your Service, call MyActivity.nbInstances() from time to time. It will return 0 a (usually short but theoretically unpredictable) while after the crash of the last running MyActivity instance. Warning: it will do so unless you have a memory leak concerning this Activity or its underlying Context as this leak would prevent the garbage collection of the instance that crashed.

  • Then you just have to start a new instance of your Activity from your Service, using startActivity(Intent)