3

Okay, I've overridden both OnSaveInstanceState and OnRestoreInstanceState and yet in OnCreate the bundle is null. I've gone through all the other related questions but they haven't worked for me. Here's my main activity.

public class MainActivity extends AppCompatActivity {
RecyclerView recyclerView;
List<Bundle> bundles;
Bundle bundle;
CustomAdapter customAdapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    if(savedInstanceState==null) {
        Log.i("abc3","savedInstanceState is null, called in OnCreate");
        bundle = new Bundle();
        bundle.putInt("productImage", R.drawable.happy);
        bundle.putString("nameOfProduct", "iPhone0");
        bundle.putString("productAmount", "5000");
        bundle.putString("nameOfDestination", "DGBDGHIDAFGK");
        bundle.putString("addressOfDestination", "Velachery Main Road, Near IIT Madras, Chennai,Tamil Nadu,India 600042");
        bundle.putString("contactno", "0123456789");
        bundle.putBoolean("isSeller", true);
        bundles = new ArrayList<>();
        bundles.add(0, bundle);
    /*Log.i("abc1", bundle.getString("nameOfProduct"));
    bundle.remove("nameOfProduct");
    bundle.putString("nameOfProduct", "iPhone1");*/
        Bundle bundle1 = new Bundle();
        bundle1.putInt("productImage", R.drawable.happy);
        bundle1.putString("nameOfProduct", "iPhone1");
        bundle1.putString("productAmount", "5000");
        bundle1.putString("nameOfDestination", "DGBDGHIDAFGK");
        bundle1.putString("addressOfDestination", "Velachery Main Road, Near IIT Madras, Chennai,Tamil Nadu,India 600042");
        bundle1.putString("contactno", "0123456789");
        bundle1.putBoolean("isSeller", true);
        bundles.add(1, bundle1);
    /*Log.i("abc1", bundle.getString("nameOfProduct"));
    bundle.remove("nameOfProduct");
    bundle.putString("nameOfProduct", "iPhone2");*/
        Bundle bundle2 = new Bundle();
        bundle2.putInt("productImage", R.drawable.happy);
        bundle2.putString("nameOfProduct", "iPhone2");
        bundle2.putString("productAmount", "5000");
        bundle2.putString("nameOfDestination", "DGBDGHIDAFGK");
        bundle2.putString("addressOfDestination", "Velachery Main Road, Near IIT Madras, Chennai,Tamil Nadu,India 600042");
        bundle2.putString("contactno", "0123456789");
        bundle2.putBoolean("isSeller", true);
        bundles.add(2, bundle2);
    }
    else
    {
        Log.i("abc3","savedInstanceState is not null,called in OnCreate");
        for(int i=0;savedInstanceState.containsKey(String.valueOf(i));++i)
            bundles.add(savedInstanceState.getBundle(String.valueOf(i)));

    }

    /*Log.i("abc1", bundle.getString("nameOfProduct"));*/
    recyclerView = (RecyclerView) findViewById(R.id.recycler_view);
    customAdapter= new CustomAdapter(this,bundles,recyclerView);
    RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
    recyclerView.setLayoutManager(mLayoutManager);
    recyclerView.setItemAnimator(new DefaultItemAnimator());
    recyclerView.setAdapter(customAdapter);
}
@Override
public void onSaveInstanceState(Bundle savedInstanceState) {

    bundles = customAdapter.getBundleList();
   // Log.i("abc3", String.valueOf(bundles.size()));
    for(int i=0;i<bundles.size();++i)
    {savedInstanceState.putBundle(String.valueOf(i),bundles.get(i));}
    super.onSaveInstanceState(savedInstanceState);
    if(savedInstanceState==null)Log.i("abc3","savedInstanceState is null, called in onSaveInstanceState");
    else Log.i("abc3","savedInstanceState is not null, called in onSaveInstanceState");
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState)
{
    if(savedInstanceState!=null)
        for(int i=0;savedInstanceState.containsKey(String.valueOf(i));++i)
            bundles.add(savedInstanceState.getBundle(String.valueOf(i)));
    super.onRestoreInstanceState(savedInstanceState);
}
}

and my manifest

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

And here's my logcat when i start the activity, then close it, then start it again.

  06-05 12:56:46.777 27184-27184/com.example.sharath.delivery_app I/abc3: savedInstanceState is null, called in OnCreate
  06-05 12:56:53.384 27184-27184/com.example.sharath.delivery_app I/abc3: savedInstanceState is not null, called in onSaveInstanceState
  06-05 12:57:00.613 27443-27443/com.example.sharath.delivery_app I/abc3: savedInstanceState is null, called in OnCreate

I've tried calling

 super.onSaveInstanceState(savedInstanceState); 

at the beginning of the method, instead of at the end, as well but there's no change.

Jacksparrow
  • 105
  • 1
  • 9
  • 1
    `yet in OnCreate the bundle is null` It is null because it isn't being recovered from saved state. `I've tried calling` No you don't call lifecycle methods yourself. The OS will do call it is needed. – Sufian Jun 05 '16 at 07:45
  • how do i recover from the saved state then? – Jacksparrow Jun 05 '16 at 08:19
  • 1
    you can read about it [here](http://stackoverflow.com/questions/6678062/when-are-all-the-cases-when-the-onsaveinstancestate-method-called) and [here](http://stackoverflow.com/questions/20831826/when-are-onsaveinstancestate-and-onrestoreinstancestate-called-exactly). For testing your save and restore, you tick the "Don't Keep Activities" inside "Developer options". Now whenever you minimize the app, your activity's `onSaveInstanceState()` will be called. And when you come back, `onCreate()` will be called before your `onRestoreInstanceState()`. – Sufian Jun 05 '16 at 08:59
  • Or for testing, you can follow the answer of Marcin Koziński, with screen rotation. – Sufian Jun 05 '16 at 09:02
  • Calling `super.onSaveInstanceState(savedInstanceState)` is perfectly all right. @Sufian must have misread and though you tried calling your method directly from somewhere. Calling through to the super method when you're overriding is perfectly all right, more than that it is necessary. – Marcin Koziński Jun 05 '16 at 09:25
  • @MarcinKoziński of course calling `super.onSaveInstanceState()` inside the overridden `onSaveInstanceState()` is okay, but the OP is calling `onSaveInstanceState()` by himself and out of that overriden method. – Sufian Jun 05 '16 at 09:34
  • @MarcinKoziński oops, I misunderstood the "I've tried calling" part in the question. :) – Sufian Jun 05 '16 at 09:49

1 Answers1

5

This behaviour looks correct. You say what you do is:

I start the activity, then close it, then start it again.

In such case Android is not going to restore the state of your activity. When the user intentionally closes an activity all state is thrown away and when they later start it they get a fresh copy.

The state is only restored when activity is recreated, because it was destroyed by the system, but the user didn't want it closed, so they expect the state of the activity to be the same. One such case is screen rotation (or in general any configuration change).

Marcin Koziński
  • 10,835
  • 3
  • 47
  • 61
  • 1
    is it possible to get the details back if the user shuts down the activity then? Overriding onStop or onPause would require me to save the data using SQLite DB or shared preferences right? – Jacksparrow Jun 05 '16 at 08:51
  • 1
    That's right. If you need to persist something you need SQLite, shared prefs or a file (see [this training from Google](https://developer.android.com/training/basics/data-storage/index.html)). "Saved instance state" is just for transient view state between activity recreations. – Marcin Koziński Jun 05 '16 at 09:16