0

I have a service that handles notifications. When I click on the notification I'm sending a Parcelable object to an Activity (NotificationActivity) :

Service :

Intent destIntent = new Intent (this, NotificationActivity.class);
destIntent.putExtra ("notificationData", new ParcelableObject (mes));

PendingIntent contentIntent = PendingIntent.getActivity (this, 0, destIntent, 0);

NotificationActivity.java :

public class NotificationActivity extends Activity {

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_notification);

        // Always NullPointerException
        ParcelableObject model = (ParcelableObject) (savedInstanceState.getParcelable ("notificationData"));

        TextView content = (TextView)findViewById(R.id.content);
        if (model == null) {
            content.setText ("NULL"); 
        } else {
            content.setText (String.valueOf (model.dump ()));
        }
    }
}

But I keep having a NullPointerException when retrieving the Object..

EDIT : After following the provided answers I have edited the code of the activity such :

@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate (savedInstanceState);
    setContentView (R.layout.activity_notification);
}

@Override
protected void onNewIntent (Intent intent) {
    super.onNewIntent (intent);

    setIntent (intent);

    // Code not executed here
    // Needed to move it to onResume () 
    // since according to the doc it comes after onNewIntent ()
}

@Override
protected void onResume () {
    super.onResume ();

    ParcelableObject model = (ParcelableObject) (getIntent ().getParcelableExtra ("notificationData"));

    Log.v ("MODEL :: ", model.dump().toString()); // NullPointerException

    TextView content = (TextView)findViewById(R.id.content);
    if (model == null) {
        content.setText ("NULL"); 
    } else {
        content.setText (String.valueOf (model.dump ()));
    }
}

Any suggestion ? Thank you.

2 Answers2

1

Adding to what tyczj said, you should try something like this to check if it's null or not:

public class NotificationActivity extends Activity {

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_notification);

        // Get from Intent if savedInstanceState is null, otherwise use saved state
        ParcelableObject model = (ParcelableObject) (savedInstanceState == null ? getIntent().getParcelableExtra("notificationData") : savedInstanceState.getParcelable("notificationData"));

        TextView content = (TextView)findViewById(R.id.content);
        if (model == null) content.setText ("NULL"); 
        else content.setText (String.valueOf (model.dump()));
    }
}

As he mentioned above, your onSaveInstance/onRestoreInstance are not always called, so relying on those methods isn't too great an idea. Instead, you may want to consider saving the data in onPause() and restoring it when the Activity resumes.

Also, if the Activity already exists and you're just opening it with a new Intent, you need to make sure you override onNewInent(Intent) in the Activity to force it to use the new Intent's data, else your new data won't be accessible. To do this, just add this below your onCreate() method:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}

That will make sure the Activity will use the latest Intent's data.

Cruceo
  • 6,763
  • 2
  • 31
  • 52
  • Thank you :) Please check my edit, I followed what you said, and still get the a NullPointerException.. –  Sep 15 '14 at 19:45
  • 1
    Can you try adding destIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); when creating the Intent for the Activity, to make sure it passes the new values? – Cruceo Sep 15 '14 at 20:23
  • You were right !! :D already upvoted, but I'll definitely accept your answer :) Would you mind explaining why this solved the problem ? and also why the code on `onNewIntent ()` is not executed except `setIntent ()` and in `onResume ()` everything's getting executed ? Thank you. –  Sep 15 '14 at 21:04
  • 1
    Of course and thanks~ As for explaining: Adding the FLAG_ACTIVITY_NEW_TASK tells the system to set the called Activity as the start of a new Task, then actually overriding onNewIntent() in the called Activity allows you set the Activity's current Intent to be that of the latest calling Intent's. onNewIntent() will only be called when the Activity already exists in the stack but is being brought back to the front with FLAG_ACTIVITY_NEW_TASK. Your issue was that it already exists, but wasn't be explicitly told to use your latest Intent's data – Cruceo Sep 15 '14 at 21:06
  • Thank you that was well explained ! :) –  Sep 15 '14 at 21:09
0

saved instance state is only use when the device rotates or something alone those lines where your activity is temporarily paused then re-created so using that there wont do anything if you are launching an activity.

you need to use getIntent() to get the object

tyczj
  • 71,600
  • 54
  • 194
  • 296