使用CLEAR_TOP重建B后,finish()无法向A返回startActivityForResult结果
现象是否符合预期?
是,这个现象完全符合Android的Activity启动规则。
原因分析
你通过startActivityForResult()从A启动的是第一个B实例,两者之间建立了请求-结果的绑定关系。但当你从D使用Intent.FLAG_ACTIVITY_CLEAR_TOP启动B时,系统会销毁栈中B之上的所有Activity(C、D);如果B的启动模式不是singleTop,还会直接销毁原来的B实例,重新创建一个全新的B实例。
这个新的B实例和A没有任何startActivityForResult的请求关联——它不是A启动的,而是从D通过CLEAR_TOP重建的。所以当你在这个新B里调用setResult()再finish()时,系统找不到对应的请求上下文,只能给A返回默认的RESULT_CANCELLED和null Intent。
解决方法
根据你的需求,有两种可行方案:
方案1:保留原B实例,避免重建
修改启动B的Intent标志,结合FLAG_ACTIVITY_CLEAR_TOP和FLAG_ACTIVITY_SINGLE_TOP:
Intent intent = new Intent(D.this, B.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); startActivity(intent);
这样系统会销毁B之上的C、D,同时调用原B实例的onNewIntent()方法而非重建。原B和A的请求关联依然存在,finish时setResult()就能正确传递给A的onActivityResult()。
如果不需要销毁C、D,只想把B调到栈顶,也可以单独使用Intent.FLAG_ACTIVITY_REORDER_TO_FRONT,同样能保留原B实例。
方案2:若必须重建B,更换数据传递方式
如果业务逻辑要求必须重建B,可以放弃startActivityForResult的结果返回机制,改用其他方式传递数据:
- 在启动B的Intent中直接携带需要返回给A的数据,在B的
onCreate()里判断是CLEAR_TOP启动后,通过EventBus、全局接口回调或Application临时存储等方式,主动把数据传递给A。 - 在B finish时,通过
startActivity启动A并携带数据,同时给A添加Intent.FLAG_ACTIVITY_CLEAR_TOP标志,让A接收数据后处理。
内容的提问来源于stack exchange,提问作者question

