2

I am trying to control my stop/restart behavior according to the Android Guidelines but it's getting a bit tricky. I want my app to restore state after being minimized and tapping the launcher icon.

The current behaviour makes so I can HOME out of the app, and when the user comes back using the long press list everything behaves as expected. Now, trying to return tapping the app icon starts the default activity, it doesn't take onRestoreInstanceState into account, and while keeping the old task affinities open on their back stack.

The activities have onCreate, onResume, onSavedInstanceState overridden, calling their super, and are of type SingleInstance.

MLProgrammer-CiM
  • 17,231
  • 5
  • 42
  • 75
  • Do you have "super.onCreate(savedInstanceState);" in your onCreate() in your class. And are you extending the "Activity" class? One way to debug this would be placing LogCat statements in onResume()/onCreate() to see if code is being executed. Also doing "super.onResume();" in onResume()? – user1406716 Jan 30 '14 at 22:48
  • Yes to both cases. Better than Logcat I'm using step by step debugging and through breakpoints I could see how the whole activity and fragments were regenerated. – MLProgrammer-CiM Jan 30 '14 at 23:50
  • I am not sure if this would help you: http://stackoverflow.com/q/6356467/1739882 – Chintan Soni Feb 04 '14 at 10:01
  • This is a good test for an app. Not everyone will need this level of robustness in their app but nonetheless a good test. – danny117 Feb 05 '14 at 06:22

3 Answers3

3

During one of my app development, I had the similar issue where app have single activity and need to save some state values (usually string, Boolean) onpause. I will give you idea how i handle it, and I hope it will useful to you also.

 protected void onPause() {
         super.onPause(); 
            saveState();

   }

  protected void onResume() {  
    super.onResume();       
    retrieveState();
  }

donot forget focus change ...

   @Override
    public void onWindowFocusChanged(boolean hasFocus) {  
      super.onWindowFocusChanged(hasFocus);
      if(hasFocus) {            
        retrieveState(); 
      }
      else { saveState(); } 
  }

Now the save and retrieve data

 public void saveState()
 {                  

     SharedPreferences settings = getSharedPreferences(WEBSTATE, 0);
 SharedPreferences.Editor editor = settings.edit();

    editor.putString(CURRENT_URL_STATE, "some url");
    editor.putInt(FILECOUNT, 10);
    /* any other content... */
   editor.commit();  

  }  


 public void retrieveState()
 {

    SharedPreferences settings = getSharedPreferences(WEBSTATE, 0);
    String current_url = settings.getString(CURRENT_URL_STATE, "");

    int count = settings.getInt((FILECOUNT, 0);

    /*use these value as per requier.. */
  }
Neha
  • 1,548
  • 2
  • 10
  • 13
  • This was pretty much my approach. Thank you. – MLProgrammer-CiM Feb 06 '14 at 10:37
  • I'd ask for only one change: onPause you can check if the activity is closing or just going to the background. The difference is important, or else you'll be saving data even when you have explicitly closed the activity. – MLProgrammer-CiM Feb 06 '14 at 22:27
  • @MLProgrammer-CiM Thanks for accepting ans. Yes your point is valid but at my application I am clearing all data @ onDestroy() bcaz if its close -> reopen my application need to start a fresh. But if its diff behave for your application then its very imp point. – Neha Feb 07 '14 at 04:03
1

The current behaviour makes so I can HOME out of the app, and when the user comes back using the long press list everything behaves as expected. Now, trying to return tapping the app icon starts the default activity, it doesn't take onRestoreInstanceState into account, and while keeping the old task affinities open on their back stack.

Let's say you got 2 activities: A and B. Activity A is your entry point, so when you tap on app icon (which in fact is incorrect statement as this is activity icon, NOT the app icon) you launch activity A. Now you got to activity B and press HOME. When you now open list of recents, you will see activity B, and will be able to get back to it. But when you tap your "app icon" on launcher screen, you will enter activity A. And this is normal and correct behavior. Also note savedInstanceState is not overall state of your application as you most likely think.

Also note, that your Activity class can be instantiated multiple times, which depending on your application architecture can, also lead to incorrect navigation behaviour. You can try to control this by using android:launchMode in your Manifest file (you will find android documentation here).

Finally, if possible, consider reworking your application to use Fragments instead of multiple activities - that would simplify controling application flow.

Marcin Orlowski
  • 72,056
  • 11
  • 123
  • 141
  • I am under the impression that you did not read the question thoroughly. I am already controlling launch mode, every activity has a nice set of fragments within the same domain. My problem comes that, unlike a hundred other apps, when tapping the "activity icon" my fragments are not regenerated to their previous state. Rather than such a condescending RTFM answer it'd better if you helped explain how to restore fragment state. – MLProgrammer-CiM Jan 30 '14 at 23:36
  • I'm running some tests on your run-of-the-mill apps (activities) and neither their request are cancelled nor their activities and fragments regenerated after reentering them, including scroll position, edittext, radiobuttons and alerts that went unmodified. I have to guess all of that wasn't packed manually on savedInstanceState. – MLProgrammer-CiM Jan 30 '14 at 23:38
  • You edited your question while I was writing my answer. You need to show your relevant code to let us help you – Marcin Orlowski Jan 31 '14 at 08:59
  • I think Marcin is right with the launchMode. If you set the main-activitiy launchMode to `singleTask` in your `manifest.xml`, your already existing main activity should be called from the back stack, instead of getting a second instance of it. you can check this if you override the `onNewIntent()` method in your main activity... – longi Jan 31 '14 at 20:27
0

Not sure if this is what you want to do, But i had a similar problem where i wanted a single base activity to return to, And i couldn't get the desired result from SingleInstance, I defined a new Activity which was the main launched :

   <intent-filter>
       <action android:name="android.intent.action.MAIN"/>
       <category android:name="android.intent.category.LAUNCHER"/>
   </intent-filter>

And from that activity i launched my desired Activity with the desired FLAG clear-top, and finished the main launched activity.

shimi_tap
  • 7,822
  • 5
  • 23
  • 23