丢失活动之间的意图附加信息

huangapple go评论83阅读模式
英文:

Losing intent extras between activities

问题

我遇到了一个问题,我在活动之间丢失了Extras。

我从MainActivity的RecyclerView发送一个ChatObject到ChatActivity,这部分正常运行。

然后我从ChatActivity将相同的ChatObject发送到GroupSettingsActivity,也正常运行。

问题是当我尝试从GroupSettingsActivity通过topAppBar的主页按钮返回到ChatActivity时,我得到一个NullPointerException,尝试从ChatObject获取ChatId。

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

我尝试过使用onResume和NavUtils,但是我一直得到相同的错误,我认为问题出在生命周期中。

这是我的MainActivity的RecyclerView适配器:

    @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);
            }
        });
    }

这是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");

    }

}

最后是GroupSettings 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);
        }
    }
英文:

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.

答案1

得分: 0

你应该在使用第二个活动中传入的值之前检查这个值是否与null不同。尝试像这样做,并设置断点以调试第二个活动中出现的情况:

第一个活动:

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

startActivity(i);

第二个活动:

Bundle extras = getIntent().getExtras();

if (extras != null) {
    Integer id = extras.getInt("user_id");
    String username = extras.getString("user_name");
}
英文:

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");
}

答案2

得分: 0

尝试在启动“ChatActivity”之前添加以下标志,以清除堆栈,并确保您创建的是一个新的“ChatActivity”,而不是重新创建旧的实例:

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

英文:

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);

答案3

得分: 0

我找到了一个解决方法,使用基于这个答案的 sharedPrefs:
https://stackoverflow.com/questions/7145606/how-do-you-save-store-objects-in-sharedpreferences-on-android

保存 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();
    }

在 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();
        }

不过这感觉有点像一个 hack,所以如果有更好的解决方案,那就太棒了。

谢谢

英文:

I found a workaround using sharedPrefs based off this answer
https://stackoverflow.com/questions/7145606/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

huangapple
  • 本文由 发表于 2020年8月21日 02:52:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/63511511.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定