Relaunching my app from same state gets failed, Oo

2019-07-19 15:02发布

问题:

What I am trying to say here is the problem I'm facing to relaunch my app from same state where it was left before. I have did lot of R&D on this and have gone through the questions posted in stackoverflow.So please it is not necessary to say that it is a duplicate.

I tried putting these options
objIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP|Intent.FLAG_ACTIVITY_SINGLE_TOP);
while starting the activity. Also I have tried this,

objIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 

And finally I tried this method also

    objIntent.setAction(Intent.ACTION_MAIN);
    objIntent.addCategory(Intent.CATEGORY_LAUNCHER); 

But none of these seem to be working for me.

The scenario goes like this, where this fails.

  1. I run my application, go to some activity from the initial activity say from A to B

  2. Now I will press my phone home button and do some actions like clicking photo and etc.

  3. Again I try to launch the app from home screen.

Oops!! Now my app has not retained its state, it is launching from the initial state.

Note:

  1. However this is not true in all the cases. some times say around 1 or 2 times out of 10 or 15 times, it launches from the same state where it was left before.

  2. One more doubt i have is do I need to set this for all the intents? Say i have some 10+ positions of Intent i.e., starting the activity. Do I need to add this piece of code in all those places? I included this for 2 or 3 cases

Update:

This works in the debug mode, but when it comes to the point of an apk create, it is getting failed. However, if I try number of times it gives me the required result and there after behaves in the way as expected. Breaking my head to understand why it happening like this.

Any one has the answer for this?

回答1:

To keep an activity running in the background is not in your hand. When you press the home button, your current activity goes to the background and can be killed (onDestroy() will be called) at any time depending on the need for memory of the other applications you launch.

The more apps you launch, the more chances of killing your background app is.



回答2:

If you want to "relaunch" your app in the same state that user left it in, you should save all your app state in the onSaveInstanceState(Bundle) method, and restore it in onRestoreInstanceState (Bundle savedInstanceState) method. Like Saurabh mentioned in the previous answer, you have no control over when your app might be killed.

You can use one of several ways to "save" your state - SharedPreferences and SQLite DB being the prominent ones.



回答3:

Yes, finally it is possible!! Thanks to google forum. I referred this https://github.com/cleverua/android_startup_activity.

What I did according to this is, create a startup activity. Inside it's oncreate method, check for a custom method called needStartApp() or something with your convention. In this get the running tasks info and compare it with our application package name. And if it is true, start your initial activity. Rest everything goes fine.

Here is the extra activity you should add,

public class StartupActivity extends Activity {

 @Override
 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (needStartApp()) {
        Intent i = new Intent(StartupActivity.this, MainActivity.class);
        startActivity(i);
    }

    finish();
}

@Override
public void onConfigurationChanged(Configuration newConfig) {
    // this prevents StartupActivity recreation on Configuration changes 
    // (device orientation changes or hardware keyboard open/close).
    // just do nothing on these changes:
    super.onConfigurationChanged(null);
}

private boolean needStartApp() {
    final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    final List<RunningTaskInfo> tasksInfo = am.getRunningTasks(1024);

    if (!tasksInfo.isEmpty()) {
        final String ourAppPackageName = getPackageName();
        RunningTaskInfo taskInfo;
        final int size = tasksInfo.size();
        for (int i = 0; i < size; i++) {
            taskInfo = tasksInfo.get(i);
            if (ourAppPackageName.equals(taskInfo.baseActivity.getPackageName())) {
                // continue application start only if there is the only Activity in the task
                // (BTW in this case this is the StartupActivity)
                return taskInfo.numActivities == 1;
            }
        }
    } 

    return true;
   }
 }

At the end, do not forget to add this permission to the manifest

    <uses-permission android:name="android.permission.GET_TASKS" />

"Android OS is really good, however it is not perfect."