Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Losing Intent extras when returning to Activity

Tags:

java

android

I have an application with a flow that is roughly:

  • Start Main Activity, enter some data
  • Start Activity A, passing a single string in the Intent
  • Activity A uses the String and gives the user some options
  • Sometimes the use will start Activity B (leaving A in background)
  • When the user returns from Activity B the Activity A is recreated (onCreate is called); I assume it has been deleted to save memory
  • The intent returned by getIntent() does NOT have the data passed to the original instance of Activity A

I know the data was there in the first call because the app would die if it was not.

I know the data is not there when the user returns to Activity A (via the 'back' key) because the app dies (null pointer from extras.getString(...) in onCreate() ).

Is this intended behaviour?

Should I be saving the contents of the extras bundle in onSaveInstanceState() ?

Edited: code snippets below:

Main Activity starts the new activity using:

Intent i = new Intent(a, BookISBNSearch.class);
i.putExtra(BookISBNSearch.BY, "isbn");
a.startActivityForResult(i, R.id.ACTIVITY_CREATE_BOOK_ISBN);

onCreate in BookISBNSearch reads this:

...
Bundle extras = getIntent().getExtras();
mIsbn = extras.getString("isbn");
String by = extras.getString(BY);
...

and a little later uses it:

if (mIsbn != null) {
    ....do some stuff....
} else if (by.equals("isbn")) {
    ....do some other stuff....

the user may start another activity from BookISBNSearch. The code that starts the new activity is:

/*
 * Start scanner activity.
 */
private void startScannerActivity() {
    if (mScannerIntent == null) {
        mScannerIntent = new Intent("com.google.zxing.client.android.SCAN");
    }
    if (!mScannerStarted) {
        mScannerStarted = true;
        startActivityForResult(mScannerIntent, ACTIVITY_SCAN);
    }
}

the user runs the scanner, does a bunch of other stuff, and eventually presses the 'back' key to return to this activity. At which point they get the crash listed below. The relevant part:

at com.eleybourn.bookcatalogue.BookISBNSearch.onCreate(BookISBNSearch.java:142)

corresponds to the line:

} else if (by.equals("isbn")) {

from which I conclude that 'by' is null.

Further, there are other possible code paths starting other (non-external) activities that exhibit the same problem. This does not occur in my phone, nor in AVD even with auto-deleting activities turned on.

It only happens for a small proportion of users.

java.lang.NullPointerException
at com.eleybourn.bookcatalogue.BookISBNSearch.onCreate(BookISBNSearch.java:142)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1050)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
at android.app.ActivityThread.access$1500(ActivityThread.java:117)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3691)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:912)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:670)
at dalvik.system.NativeStart.main(Native Method)
like image 351
RabidMutant Avatar asked Apr 29 '12 11:04

RabidMutant


1 Answers

Try writing your Intent-data to the savedInstance!

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

    if(getIntent() != null) {
        // Activity was started and got an Intent with data
        ...
    } else if(savedInstanceState != null) {
        // No intent is available, try getting data from savedInstance
        ...
    }

}

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    if(outState != null) {
        // Write here your data
        ...
    }
}

I hope this was helpful :)

like image 117
dudeldidadum Avatar answered Sep 28 '22 15:09

dudeldidadum