话题:关于startActivityForResult
问题1. startActivityForResult的使用场景是什么?onActivityResult回调里面的resultCode和requestCode含义是什么?
- 使用场景是在于,启动一个activity的时候,需要有返回值(选择图片,选择收货地址,选择联系人)。
- requestCode 请求码, 是为了解决 区分多个异步任务 ,可以通过其判断是从哪一个场景下启动的activity.
- resultCode 结果码 ,通过setResult设置,可以传递结果,告诉调用者成功/失败/其他信息,还可以告知是由哪一个activity返回的.
/** Standard activity result: operation canceled. */
public static final int RESULT_CANCELED = 0;
/** Standard activity result: operation succeeded. */
public static final int RESULT_OK = -1;
/** Start of user-defined activity results. */
public static final int RESULT_FIRST_USER = 1;
问题2. Activity A启动B的时候,在B中何时该执行setResult?setResult可以位于Activity的finsh方法之后嘛?
public final void setResult(int resultCode, Intent data) {
synchronized (this) {
mResultCode = resultCode;
mResultData = data;
}
}
private void finish(int finishTask) {
if (mParent == null) {
int resultCode;
Intent resultData;
synchronized (this) {
resultCode = mResultCode;
resultData = mResultData;
}
if (false) Log.v(TAG, "Finishing self: token=" + mToken);
try {
if (resultData != null) {
resultData.prepareToLeaveProcess(this);
}
if (ActivityManager.getService()
.finishActivity(mToken, resultCode, resultData, finishTask)) {
mFinished = true;
}
} catch (RemoteException e) {
// Empty
}
} else {
mParent.finishFromChild(this);
}
}
上述源码可以知道,setResult会将resultCode,data赋值给mResultCode 与mResultData . 在activity finsh的时候会去取这两个数的值.
然后通过传递给AMS -- ActivityStack -- ActivityRecord(加到list relaunchActivityLocked) -- ActivityThread(scheduleRelaunchActivity -- deliverResults) --Activity(dispatchActivityResult) 回调onActivityResult
所以setResult一定要在B中执行finsh之前,不可位于finsh之后.
- back键会调用finsh(); 或者显示调用finsh();
- onStart ,onResume , onPause , onStop , onDestroy ,均有可能在finsh()之后调用
扩充问题3. startActivityForResult 与启动模式冲突吗?
5.0以上版本的时候 , startActivityForResult 为了获取到正常的回调,会导致singleTask 和singleinstance失效,android认为不同的task之间应该不能获取信息,为了不创建新的task,
如果重复的使用startActivityForResult启动自己, 无论什么启动模式,都会一直创建新的activity实例
adb shell dumpsys activity activities
4.4.4以下版本,如果使用的是singleTask 和singleinstance ,onActivityResult收到RESULT_CANCELED会直接返回data=null, resultCode = 0.