android.app.Fragment包下的startActi

2017-08-16  本文已影响57人  做实事的人
/**
     * Call {@link Activity#startActivityForResult(Intent, int, Bundle)} from the fragment's
     * containing Activity.
     */
    public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
        if (mHost == null) {
            throw new IllegalStateException("Fragment " + this + " not attached to Activity");
        }
        mHost.onStartActivityFromFragment(this, intent, requestCode, options);
    }

android.app.Fragment 类中有这么一个Callback,这个Callback是android.app.FragmentHostCallback的一个实例,从这个类的注释中看到,Fragment肯定是有宿主的,正如Activity中去开启一个Fragment,这个Activity就是Fragment的宿主了,这个Callback就是用来回调宿主中的一些方法的。

// Activity this fragment is attached to.
    FragmentHostCallback mHost;

看这个android.app.FragmentHostCallback的一个方法,最终会调用startActivity,这个很明显就是Activity中的方法,所以确定了这个类的作用以后,会更加的清晰我们继续分析下去的流程。

/**
     * Starts a new {@link Activity} from the given fragment.
     * See {@link Activity#startActivityForResult(Intent, int)}.
     */
    public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode,
            Bundle options) {
        if (requestCode != -1) {
            throw new IllegalStateException(
                    "Starting activity with a requestCode requires a FragmentActivity host");
        }
        mContext.startActivity(intent);
    }

其实上面的方法不是真正的执行流程, Activity中有HostCallbacks这个东西里面重写了上面onStartActivityFromFragment方法

class HostCallbacks extends FragmentHostCallback<Activity> {
        public HostCallbacks() {
            super(Activity.this /*activity*/);
        }

       ...省略一些不必要的方法
        @Override
        public void onStartActivityFromFragment(Fragment fragment, Intent intent, int requestCode,
                Bundle options) {
            //这里就是重写了的方法,重点分析startActivityFromFragment
            Activity.this.startActivityFromFragment(fragment, intent, requestCode, options);
        }
...省略一些不必要的方法

下面就是startActivityFromFragment的主要逻辑

/**
     * This is called when a Fragment in this activity calls its
     * {@link Fragment#startActivity} or {@link Fragment#startActivityForResult}
     * method.
     *
     * <p>This method throws {@link android.content.ActivityNotFoundException}
     * if there was no Activity found to run the given Intent.
     *
     * @param fragment The fragment making the call.
     * @param intent The intent to start.
     * @param requestCode Reply request code.  < 0 if reply is not requested.
     * @param options Additional options for how the Activity should be started.
     * See {@link android.content.Context#startActivity(Intent, Bundle)
     * Context.startActivity(Intent, Bundle)} for more details.
     *
     * @throws android.content.ActivityNotFoundException
     *
     * @see Fragment#startActivity
     * @see Fragment#startActivityForResult
     */
    public void startActivityFromFragment(@NonNull Fragment fragment,
            @RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) {
        startActivityForResult(fragment.mWho, intent, requestCode, options);
    }

    /**
     * @hide
     */
    @Override
    public void startActivityForResult(
            String who, Intent intent, int requestCode, @Nullable Bundle options) {
        Uri referrer = onProvideReferrer();
        if (referrer != null) {
            intent.putExtra(Intent.EXTRA_REFERRER, referrer);
        }
        options = transferSpringboardActivityOptions(options);
        Instrumentation.ActivityResult ar =
            mInstrumentation.execStartActivity(
                this, mMainThread.getApplicationThread(), mToken, who,
                intent, requestCode, options);
        if (ar != null) {
            mMainThread.sendActivityResult(
                mToken, who, requestCode,
                ar.getResultCode(), ar.getResultData());
        }
        cancelInputsAndStartExitTransition(options);
    }
上一篇下一篇

猜你喜欢

热点阅读