0

I'm having an issue where I'm losing Extras between activites.

I'm sending a ChatObject from a MainActivity Recyclerview to a ChatActivity, and it works fine.

I then send the same ChatObject from the ChatActivity to a GroupSettingsActivity, which also works fine.

My issue is when I try to return from the GroupSettingsActivity to the ChatActivity from my topAppBar home button, I get a nullPointerException trying to getChatId from the ChatObject.

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.shotgunnot/com.example.shotgunnot.ChatActivity}: 
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String com.example.shotgunnot.Chat.ChatObject.getChatId()' on a null object reference

I've tried using onResume, and Navutils but I keep getting the same error, I think it's something in the life cycle im not getting. Androids built in back nav button works as expected.

Here's my MainActivity recyclerview adapter

    @Override
    public void onBindViewHolder(@NonNull final ChatListViewHolder holder, final int position) {
        ChatObject data = chatList.get(position);

        holder.mTitle.setText(data.getChatId());
        holder.mGroup.setText(data.getGroupId());

        System.out.println("GroupPic" + data.getGroupPic());
        Glide.with(context)
                .load(data.getGroupPic())
                .diskCacheStrategy(DiskCacheStrategy.ALL)
                .placeholder(R.drawable.ic_group_24dp)
                .apply(RequestOptions.circleCropTransform().circleCrop())
                .into(holder.mGroupPic);

        holder.mLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(v.getContext(), ChatActivity.class);
                intent.putExtra("chatObject", chatList.get(holder.getBindingAdapterPosition()));
                v.getContext().startActivity(intent);
            }
        });
    }

This is the chatActivity

public class ChatActivity extends AppCompatActivity  {

    ChatObject mChatObject;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_chat);

        Intent intent = getIntent(); >> 
        mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");

        BottomAppBar bottomAppBar = findViewById(R.id.bottomAppBar);
        bottomAppBar.replaceMenu(R.menu.group_menu);
        bottomAppBar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.settings:
                        Intent intent = new Intent(ChatActivity.this, GroupSettingsActivity.class);
                        intent.putExtra("chatObject", mChatObject);
                        startActivity(intent);
                        return true;
                    case android.R.id.home:
                        Intent home = new Intent(getApplicationContext(), MainPageActivity.class);
                        startActivity(home);
                }
                return false;
            }
        });

    }

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

        Intent intent = getIntent();
        mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");

    }

}


And finally the GroupSetting Activity

public class GroupSettingsActivity extends AppCompatActivity {
    ChatObject mChatObject;


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

        Intent intent = getIntent(); 

        mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");
        chatId = mChatObject.getChatId();

    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
            case android.R.id.home:
                Intent intent = new Intent(this, ChatActivity.class);
                intent.putExtra("chatObject", mChatObject);
                startActivity(intent);
                //NavUtils.navigateUpFromSameTask(this);
                finish();
            default:
                return super.onOptionsItemSelected(item);
        }
    }

Any help would be much appreciated.

byrnec25
  • 29
  • 5
  • `Intent intent = new Intent(this, ChatActivity.class);` That should be: `Intent intent = getIntent();`. – blackapps Aug 20 '20 at 18:58
  • `startActivity(intent);` No. Throw that line away. You only should yet set a result before you call finish(). – blackapps Aug 20 '20 at 19:00
  • Thanks for the input but I'm not sure I understand what you mean. Intent intent = new Intent(this, ChatActivity.class); & startActivity(intent); are going back to the 1st activity. Where intent = getIntent(); is receving in the 2nd activity – byrnec25 Aug 20 '20 at 19:39

3 Answers3

0

You should check if the value that is arriving in the second activity is different from null before using it. Try to do something like this and put a breakpoint to debug what's coming up in your second activity:

1st Activity:

Intent i = new Intent(getApplicationContext(), NewActivity.class);
i.putExtra("user_id", "1234");
i.putExtra("user_name", "John Doe");

startActivity(i);

2nd Activity:

Bundle extras = getIntent().getExtras();

if (extras != null) {
    Integer id= extras.getInt("user_id");
    String username= extras.getString("user_name");
}
Liam Park
  • 414
  • 1
  • 9
  • 26
  • Thanks for the tip, I have tried that. I am able to use the object in the 2nd Activity. eg mChatObject.getChatId() but when I return to the 1st activity the extras are null. – byrnec25 Aug 20 '20 at 19:26
  • Maybe Android do not preserve the Extras to free memory so if you need to use the Extras that you send to activity 2 in activity 1 again when pressing back button, you should resend the extras – Liam Park Aug 20 '20 at 19:36
  • Yeah that's what I'm trying I'm sending the same object like so intent.putExtra("chatObject", mChatObject); and receiving like so- Intent intent = getIntent(); mChatObject = (ChatObject) intent.getSerializableExtra("chatObject"); – byrnec25 Aug 20 '20 at 19:41
  • I have a feeling it's to do with the lifecycle, because if I finish the 1st activity after sending the extras, the extras are received from the 2nd to the 1st. But then I have other navigation issues. – byrnec25 Aug 20 '20 at 19:44
0

Try to add these flags before starting ChatActivity, to clear the stack and make sure you're creating a new ChatActivity rather then recreating an old one:

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);

Tal Mantelmakher
  • 994
  • 1
  • 7
  • 23
0

I found a workaround using sharedPrefs based off this answer How do you save/store objects in SharedPreferences on Android?

saving prefs

    @Override
    protected void onPause() {
        super.onPause();
        SharedPreferences.Editor prefsEditor = mPrefs.edit();
        Gson gson = new Gson();
        String json = gson.toJson(mChatObject);
        prefsEditor.putString("mChatObject", json);
        prefsEditor.commit();
    }

And retrieving them in onCreate

        mChatObject = (ChatObject) intent.getSerializableExtra("chatObject");
        if(mChatObject != null){
            chatId = mChatObject.getChatId();
            groupId = mChatObject.getGroupId();
            groupPic = mChatObject.getGroupPic();
        }else{
            Gson gson = new Gson();
            String json = mPrefs.getString("mChatObject", "");
            mChatObject = (ChatObject) gson.fromJson(json, ChatObject.class);
            chatId = mChatObject.getChatId();
            groupId = mChatObject.getGroupId();
            groupPic = mChatObject.getGroupPic();
        }

It feels like a bit of hack though, so if anyone has a better solution that'd be great.

Thanks

byrnec25
  • 29
  • 5