关于startActivityForResult
Question¶
话题:关于startActivityForResult
- startActivityForResult的使用场景是什么?onActivityResult回调里面的resultCode和requestCode含义是什么?
- Activity A启动B的时候,在B中何时该执行setResult ?setResult可以位于Activity的finish方法之后吗?
Answer¶
1. startActivityForResult的使用场景是什么?onActivityResult回调里面的resultCode和requestCode含义是什么?
-
使用场景
startActivityForResult就是两个Activity间进行信息交流的一种手段。 -
resultCode、requestCode含义 requestCode是为了解决多个请求的区分问题。
resultCode是请求结果码,告诉调用者成功/失败等消息。该信息被调用Activity写入,并经过AMS传递给源Activity
2. Activity A启动B的时候,在B中何时该执行setResult?setResult可以位于Activity的finish方法之后吗?
setResult在finish之前执行,该方法只是将数据记录在Activity的mResultCode和mResultData中。
如果setResult在finish之后执行,那么消息无法传递给源Activity
Activity#finish时序图如下所示, 
关键节点:
Client端通过AMP把数据发送给Server端AMS Binder实体- AMS把数据包装成
ActivityResult并保存在源ActivityRecord的results变量中 - AMS通过
ApplicationThreadProxy向Client端发送pause信息让栈顶Activity进入paused状态,并等待Client端回复或超时 - AMS接收Client端已paused信息,恢复下一个获取焦点的
Activity,读取之前保存在ActivityRecord.results变量的数据派发给Client端对应的 Activity - Client端数据经过
ApplicationThread对象、ActivityThread对象的分发最后到达Activity
存疑:startActivityForResult 和 singleTask 导致源 Activity 收不到正确结果问题
源Activity和目标Activity无法在跨Task情况下通过onActivityResult传递数据
Android5.0以上AMS在处理manifest.xml文件中的singleTask和singleInstance信息「不会」创建新的Task,因此可以收到正常回调 7.0.0_r1
Android4.4.4以下AMS在处理manifest.xml文件中的singleTask和singleInstance信息「会」创建新的Task,因此在startActivity之后立即收到取消的回调 4.4.4_r1
通过dumpsys activity activities命令查看AMS状态,验证两个Activity是否属于不同的Task