Android setIntent()不会在重新创建的活动中保留新值

时间:2017-08-27 17:43:52

标签: android android-intent android-pendingintent

我的一项活动(A)是通过提供的PendingIntent通过推送通知启动的。如果这个意图有一定的关键,那么我需要开始一个新的活动(B)。按回B,我应该返回A.如果我启用"不要保持活动"通过开发人员设置,A在启动B后显然被杀死,这意味着从B返回到A时,A用原始意图(具有额外的键)重新创建 - 再次启动B - 并且导致用户被卡住乙

作为一种解决方法,我尝试在启动B并重置意图之前删除A中的额外键。此代码来自活动A中的onCreate()方法。我添加了AlarmManager以轻松复制行为 - 它与我的问题无关。

    Intent originalIntent = getIntent();
    if(originalIntent != null && originalIntent.hasExtra("A")){
        Log.d(TAG, "onCreate: has A" );
        startActivity(new Intent(this, PAlarmTwo.class));
        originalIntent.removeExtra("A");
        setIntent(originalIntent);
        Log.d(TAG, "onCreate: modified intent has A : " + getIntent().hasExtra("A"));
    } else {
        Log.d(TAG, "onCreate: no A");
    }

    final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent alarmIntent = new Intent(PAlarmOne.this, PAlarmOne.class);
            alarmIntent.putExtra("A", "a");
            PendingIntent pendingIntent = PendingIntent.getActivity(PAlarmOne.this, 1, alarmIntent, 0);
            alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+1000, pendingIntent);
        }
    });

日志表明虽然setIntent()在启动B之前删除了密钥,但重新创建的A会使用密钥获取旧的意图。基本上,从不打印日志("没有A")。

我试过了2个解决方案:

  1. 传递PendingIntent.FLAG_ONE_SHOT以创建PendingIntent。根据文档,它应该工作,但它不是。我对这面旗帜的理解是错误的吗?
  2. 在活动A中设置实例变量,指示意图是否已被使用过一次。我可以通过onSaveInstanceState()从外部持久保存此变量,它将在同一活动的重新创建的实例中持续存在。对于引入新变量来跟踪多个生命周期方法,这种方法并不干净。

2 个答案:

答案 0 :(得分:0)

  

A在启动B后显然被杀死,这意味着从B返回到A时,A会以原始意图(具有额外的键)重新创建 - 再次启动B - 这会导致用户被卡在B上

您应该在保存的实例状态Bundle中保存状态,告诉您是否应该启动B.

  

日志表明虽然setIntent()在启动B之前删除了密钥,但重新创建的A会使用密钥获取旧的意图。

我的猜测是setIntent()仅影响当前实例。它不会将指令发送回核心操作系统,以某种方式将此新Intent与Android将用于重新创建A的后堆栈记录相关联。

  

我对这面旗帜的理解是错误的吗?

该标志控制PendingIntent。它不会影响由Intent包含的PendingIntent启动的组件。

  

这种方法感觉不干净,因为引入了一个新变量来跟踪多个生命周期方法。

欢迎您的意见。活动状态涉及很多事情,包括可能只需要调用一次的大量事情(例如,数据加载,确认消息)。这只是另一个。

答案 1 :(得分:0)

本教程对我有用:http://www.helloandroid.com/tutorials/communicating-between-running-activities

 public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
             setContentView(R.layout.main);
           processExtraData();
                }

protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
 setIntent(intent);//must store the new intent unless getIntent() will return the old 
one
processExtraData()
 }

private void processExtraData(){
Intent intent = getIntent();
//use the data received here
}