如何让Activity A获取到被clearTop重启的Activity B的返回结果?
当Activity C用FLAG_ACTIVITY_CLEAR_TOP启动Activity B时,系统会销毁栈中B之上的所有Activity(这里就是C),同时销毁原来的B实例并重建一个新的B实例。而原来的B是由A通过startActivityForResult()(或新版的registerForActivityResult())启动的,这个旧B实例被销毁时,会自动向A返回RESULT_CANCELLED;而新创建的B实例和A之间并没有启动-返回的关联,所以新B调用setResult(RESULT_OK)结束时,A根本接收不到这个结果。
方法1:复用已有B实例(推荐)
在C启动B的Intent里,同时加上FLAG_ACTIVITY_SINGLE_TOP和FLAG_ACTIVITY_CLEAR_TOP。这样系统会复用栈中已有的B实例,不会销毁重建。此时需要在B中重写onNewIntent()方法,处理C传递过来的数据,之后当B结束时调用setResult(),就能正常把结果返回给A。
代码示例:
// Activity C中启动B的代码 Intent intent = new Intent(this, ActivityB.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); // 传递需要给B的数据 intent.putExtra("key", "value from C"); startActivity(intent); // Activity B中重写onNewIntent @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); // 更新当前Intent为新传入的Intent(可选,方便后续获取数据) setIntent(intent); // 处理C传递过来的数据,比如更新页面状态 String data = intent.getStringExtra("key"); } // 当B需要返回结果给A时,正常调用 Intent resultIntent = new Intent(); resultIntent.putExtra("result", "final data"); setResult(RESULT_OK, resultIntent); finish();
方法2:临时存储结果再传递
如果业务必须重建B实例,可以在C中把要返回给A的结果先存在全局存储(比如SharedPreferences、自定义Application类的全局变量,或者ViewModel)里。新的B实例启动后,读取这个临时结果,在finish时调用setResult()返回给A。
注意:用完临时数据后要及时清理,避免数据混乱或内存泄漏。
方法3:调整跳转流程
如果业务允许,直接让C返回结果给原来的B,而不是重启B。比如C调用setResult()后finish,让原来的B回到前台,再由B处理结果并返回给A。
代码示例:
// Activity C中返回结果给B Intent resultToB = new Intent(); resultToB.putExtra("data_from_c", "content"); setResult(RESULT_OK, resultToB); finish(); // Activity B中接收C的结果(前提是B启动C时用了startActivityForResult/registerForActivityResult) @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_C && resultCode == RESULT_OK) { // 处理C返回的数据,再打包返回给A Intent resultToA = new Intent(); resultToA.putExtra("final_result", data.getStringExtra("data_from_c")); setResult(RESULT_OK, resultToA); finish(); } }
内容的提问来源于stack exchange,提问作者Mehroze Yaqoob

