OnBackPress 在 android 中表现不同

OnBackPress behaving differently in android

我有 3 个活动:ABC。当我在 activity 中点击 RecyclerView 中的项目时 A activity B 将被打开。我从 A 传递了一些 String 值到 B.
在 activity B 中,当我点击一个按钮时,我会转到 activity C。在 C 中,当我从 phone(android 默认后退按钮)按下后退按钮时,它会正常返回到 activity B 。但我还使用父 activity 在 ToolBar 中放置了一个后退按钮。当我按下该按钮时,它显示错误,试图在 activity B 中检索的 String 值为空。我明白为什么会显示错误。很明显是因为没有字符串从C传给B去取
但是,当我从 phone 的默认按钮返回时,为什么我没有收到此错误消息?我该如何解决这个问题?

Activity一个

Intent intent = new Intent(getActivity(), Chat.class);
intent.putExtra("Recievers_Id", userId);
intent.putExtra("Recievers_Name", userName);
startActivity(intent);

Activity B

MessageSenderId = mAuth.getCurrentUser().getUid();
MessageRecieverId = getIntent().getStringExtra("Recievers_Id");
MessageRecieverName = getIntent().getStringExtra("Recievers_Name");

Activity C

Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);

上出错
MessageRecieverId = getIntent().getStringExtra("Recievers_Id"); 
MessageRecieverName = getIntent().getStringExtra("Recievers_Name"); 

因为显然没有什么可取的...我该如何解决这个问题

onClickListener 添加到工具栏的后退按钮:

toolbar.setNavigationOnCLickListener(new View.OnClickListener){
    @Override
    public void onClick(View view) {
        finish();
    }
});

如果您遇到 null 错误,请尝试以下操作:

if(getIntent().getStringExtra("Recievers_Id") != null){
    MessageRecieverId = getIntent().getStringExtra("Recievers_Id"); 
}
if(getIntent().getStringExtra("Recievers_Name") != null){
    MessageRecieverName = getIntent().getStringExtra("Recievers_Name"); 
}

您可以将工具栏上的后退按钮设置为:

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    switch (id) {
        // Respond to the action bar's Up/Home button
        case android.R.id.home:
            //NavUtils.navigateUpFromSameTask(this);
            onBackPressed();
            return true;
    }
    return super.onOptionsItemSelected(item);
}

首先,您需要了解当用户按下向上导航按钮时会发生什么以及 onBackPressed.

时会发生什么

基于documentation

  • If the parent activity has launch mode <singleTop>, or the up intent contains FLAG_ACTIVITY_CLEAR_TOP, the parent activity is brought to the top of the stack, and receives the intent through its onNewIntent() method.
  • If the parent activity has launch mode , and the up intent does not contain FLAG_ACTIVITY_CLEAR_TOP, the parent activity is popped off the stack, and a new instance of that activity is created on top of the stack to receive the intent.

当按下后退按钮时,它会按时间倒序浏览屏幕的历史记录。在这种情况下 Activity 不会被重新创建。

总而言之,AndroidManifest.xml 中的 ActivityB 的启动模式必须是 standard。在这种情况下,当您按下向上导航按钮时,将重新创建 activity。但是当按下后退按钮时,ActivityB 只是被带到前面,因此行为有所不同。

解法:

方法一:自己操作向上按钮

@Override
public boolean onOptionsItemSelected(MenuItem item) {

    if(item.getItemId()== android.R.id.home {
        onBackPressed();
        return true;
    }
    return super.onOptionsItemSelected(item);
}

方法二:

将 Activity B 的启动模式设置为 AndroidManifest.xml 中的 singleTop。请记住检查更改 launch mode.

的含义

The "standard" and "singleTop" modes differ from each other in just one respect: Every time there's a new intent for a "standard" activity, a new instance of the class is created to respond to that intent. Each instance handles a single intent. Similarly, a new instance of a "singleTop" activity may also be created to handle a new intent. However, if the target task already has an existing instance of the activity at the top of its stack, that instance will receive the new intent (in an onNewIntent() call); a new instance is not created.

在 activity B 你应该检查 Intent 是否已请求 Extra.

Intent i = getIntent();
if (i.hasExtra("Recievers_Id")) {
    messageRecieverId = i.getStringExtra("Recievers_Id");
} 
if (i.hasExtra("Recievers_Name")) {
    messageRecieverName= i.getStringExtra("Recievers_Name");
}