user1079425
user1079425

Reputation:

NullPointerException : Get Parcelable data from intent

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.

Upvotes: 0

Views: 902

Answers (2)

Cruceo
Cruceo

Reputation: 6834

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.

Upvotes: 1

tyczj
tyczj

Reputation: 73753

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

Upvotes: 0

Related Questions