英文:
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
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论