Android startActivityForResult

今天来总结下 startActivityForResult的相关知识,虽然这块很简单,但是基础打好很重要哦。


Intent intent = new Intent(MainActivity.this, Main2Activity.class);
startActivityForResult(intent, 99);
startActivityForResult 的使用场景是什么?

Activity在finish的时候需要向上一个Activity传值的时候,我们就可以使用startActivityForResult。比如打开相册选取照片,拍照,关闭页面需要返回一个参数给打开我们的页面。

onActivityResult 回调里面的 resultCode 和 requestCode 含义是什么?

由于每个activity都可以启动任意的子activity并等待结果,而结果处理函数只有一个onActivityResult(int requestCode, int resultCode, Intent intent),因此为了区别请求的activity,android将每个请求设定一个大于等于0的int值,这就是requestCode。由此,在onActivityResult函数中即可利用requestCode区别开不同的返回结果。
而onActivityResult中的resultCode参数对应于子模块中setResut(int resultCode, Intent intent)函数中的resultCode值,用于区别不同的返回结果(如请求正常、请求异常等)。

Activity A 启动 B 的时候,在 B 中何时该执行 setResult?setResult 可以位于 Activity 的 finish 方法之后吗?

result是在被finish的时候,也就是说调用setResult()方法必须在finish()之前。
那么如果在如下方法中调用setResult()也有可能不会返回成功: onPause(), onStop(), onDestroy()。

源码分析
 public void startActivityForResult(Intent intent, int requestCode) {
        if (!this.mStartedActivityFromFragment && requestCode != -1) {
            checkForValidRequestCode(requestCode);
        }

        super.startActivityForResult(intent, requestCode);
    }

static void checkForValidRequestCode(int requestCode) {
        if ((requestCode & -65536) != 0) {
            throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");
        }
    }

我们通过看startActivityForResult的源码发现,通过checkForValidRequestCode 如果requestCode是负数就会抛出IllegalArgumentException。因为源码原因没办法继续追下去了。

 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);
        }

        // Activity was launched when user tapped a link in the Autofill Save UI - Save UI must
        // be restored now.
        if (mIntent != null && mIntent.hasExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN)) {
            getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_RESTORE,
                    mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
        }
    }

为什么setResult要在finish之前,因为在finish内会调用 resultData.prepareToLeaveProcess(this);
ActivityManager.getService() ..finishActivity(mToken, resultCode, resultData, finishTask))方法,这样才能把相关参数传递回去。


你可能感兴趣的:(Android startActivityForResult)