Fragment调用startActivityForResult过程笔记

来源:互联网 发布:如何将js压缩成min.js 编辑:程序博客网 时间:2024/06/08 03:41

在Fragment中调用startActivityForResult方法可以在onActivityResult方法中收到回应。

Fragment中startActivityForResult部分源码:

    /**     * Call {@link Activity#startActivityForResult(Intent, int)} on the fragment's     * containing Activity.     */    public void startActivityForResult(Intent intent, int requestCode) {        if (mActivity == null) {            throw new IllegalStateException("Fragment " + this + " not attached to Activity");        }        mActivity.startActivityFromFragment(this, intent, requestCode);    }
FragmentActivity中startActivityFromFragment部分源码:
    /**     * Called by Fragment.startActivityForResult() to implement its behavior.     */    public void startActivityFromFragment(Fragment fragment, Intent intent,             int requestCode) {        if (requestCode == -1) {            super.startActivityForResult(intent, -1);            return;        }        if ((requestCode&0xffff0000) != 0) {            throw new IllegalArgumentException("Can only use lower 16 bits for requestCode");        }        super.startActivityForResult(intent, ((fragment.mIndex+1)<<16) + (requestCode&0xffff));    }

注:<<操作符表示当前值数的二进制左移16位,低位补0。对16进制来说,就是左移4位,低位补0。

方法中判断符合条件以后,在最后一句代码将Fragment在activity的index+1放入一个16进制int值的高四位,将requestCode截取低四位(已经限定requestCode不能大于0xffff)放入16进制int值的低四位,组成一个requestCode参数使用。

FragmentActivity中startActivityFromFragment部分源码:

    /**     * Dispatch incoming result to the correct fragment.     */    @Override    protected void onActivityResult(int requestCode, int resultCode, Intent data) {        mFragments.noteStateNotSaved();        int index = requestCode>>16;        if (index != 0) {            index--;            if (mFragments.mActive == null || index < 0 || index >= mFragments.mActive.size()) {                Log.w(TAG, "Activity result fragment index out of range: 0x"                        + Integer.toHexString(requestCode));                return;            }            Fragment frag = mFragments.mActive.get(index);            if (frag == null) {                Log.w(TAG, "Activity result no fragment exists for index: 0x"                        + Integer.toHexString(requestCode));            } else {                frag.onActivityResult(requestCode&0xffff, resultCode, data);            }            return;        }                super.onActivityResult(requestCode, resultCode, data);    }
首先将回调的requestCode值16进制右移四位取高四位值,如果不是0,表示这是Fragment调用startActivityForResult方法的回调,需要回调Fragment的onActivityResult方法。如果是0,则是当前activity调用的startActivityForResult方法(在此方法中已经限定requestCode不能大于0xffff),直接使用super.onActivityResult(requestCode, resultCode, data);交给父类处理。

在if语句块内,将requestCode拆分,16进制高四位表示Fragment的index+1,低四位是Fragment的requestCode,回调Fragment的onActivityResult方法。

流程结束。

另:当activity设置启动模式为singleInstance时,调用startActivityForResult方法会直接回调onActivityResult方法,所以此时Fragment调用startActivityFroResult方法也不好使。

api说明:Note that this method should only be used with Intent protocols that are defined to return a result. In other protocols (such asIntent.ACTION_MAIN or Intent.ACTION_VIEW), you may not get the result when you expect. For example, if the activity you are launching uses the singleTask launch mode, it will not run in your task and thus you will immediately receive a cancel result.



0 1