android调用系统分享启动过程分析

/ android / 没有评论 / 1156浏览

用到的代码文件

frameworks/base/core/java/:
android/content/Intent.java
com/android/internal/app/ChooserActivity.java
com/android/internal/app/ResolverActivity.java
com/android/internal/app/ResolverListController.java

代码执行流程图

android system share 查看原图

系统分享界面启动流程

下面的代码基于android O(api 27)。

本文基于MTK(MediaTek)平台基线。

本文主要记录公司某文件管理器app中点击某个文件进行分享的流程,因此并不适用于所有android系统分享界面的启动流程,具体问题须对照源码具体分析,但是思路基本一致。

当在应用上点击share按钮的时候首先调用Intent类中createChooser()这个方法。

public static Intent createChooser(Intent target, 
        CharSequence title) {
    /*target: Intent { act=android.intent.action.SEND
     typ=application/vnd.android.package-archive
     flg=0x3 (has extras) } title: Share file(s) via*/
    Log.w("Intent", "method createChooser() target: " 
            + target + " title: " + title);
    return createChooser(target, title, null);
}

接下来调用Intent.java中的createChooser()重载方法。

public static Intent createChooser(Intent target, 
        CharSequence title, IntentSender sender) {
    /*method createChooser() target:
     Intent { act=android.intent.action.SEND 
     typ=application/vnd.android.package-archive 
     flg=0x3 (has extras) } title: Share file(s) 
     viasender: null*/
    log("method createChooser() target: " + target 
        + " title: " + title + "sender: " + sender);
    Intent intent = new Intent(ACTION_CHOOSER);
    intent.putExtra(EXTRA_INTENT, target);
    if (title != null) {// -> true
        intent.putExtra(EXTRA_TITLE, title);
    }
    if (sender != null) { // -> false
        intent.putExtra(EXTRA_CHOSEN_COMPONENT_INTENT_SENDER, 
                sender);
    }
    // Migrate any clip data and flags from target.
    int permFlags = target.getFlags() 
            & (FLAG_GRANT_READ_URI_PERMISSION
            | FLAG_GRANT_WRITE_URI_PERMISSION 
            | FLAG_GRANT_PERSISTABLE_URI_PERMISSION
            | FLAG_GRANT_PREFIX_URI_PERMISSION);
    if (permFlags != 0) {
        //permFlags: 3
        log("permFlags: "+permFlags);
        ClipData targetClipData = target.getClipData();
        if (targetClipData == null && target.getData() != null) {
        // -> false
            ClipData.Item item = new ClipData.Item(target.getData());
            String[] mimeTypes;
            if (target.getType() != null) {
                mimeTypes = new String[] { target.getType() };
            } else {
                mimeTypes = new String[] { };
            }
            targetClipData = new ClipData(null, mimeTypes, item);
        }
        if (targetClipData != null) {// -> false
            intent.setClipData(targetClipData);
            intent.addFlags(permFlags);
        }
    }
    return intent;
}

至此启动ChooserActivity的Intent构造完成,下面进入ChooserActivity的onCreate()方法中。

@Override
protected void onCreate(Bundle savedInstanceState) {
    log("method onCreate()");
    final long intentReceivedTime = System.currentTimeMillis();
    mIsSuccessfullySelected = false;
    Intent intent = getIntent();
    Parcelable targetParcelable = 
        intent.getParcelableExtra(Intent.EXTRA_INTENT);
    if (!(targetParcelable instanceof Intent)) {// -> false
        Log.w("ChooserActivity", "Target is not an intent: " 
            + targetParcelable);
        finish();
        super.onCreate(null);
        return;
    }
    Intent target = (Intent) targetParcelable;
    if (target != null) {// -> true
        //修改target intent的启动flag
        modifyTargetIntent(target);
    }
    Parcelable[] targetsParcelable
            = intent.getParcelableArrayExtra(
                Intent.EXTRA_ALTERNATE_INTENTS);
    if (targetsParcelable != null) { // -> false
        ......
    }

    mReplacementExtras = intent
        .getBundleExtra(Intent.EXTRA_REPLACEMENT_EXTRAS);
    CharSequence title = intent
        .getCharSequenceExtra(Intent.EXTRA_TITLE);
    int defaultTitleRes = 0;
    if (title == null) {// -> false
        defaultTitleRes = 
            com.android.internal.R.string.chooseActivity;
    }
    Parcelable[] pa = intent
        .getParcelableArrayExtra(Intent.EXTRA_INITIAL_INTENTS);
    Intent[] initialIntents = null;
    if (pa != null) { // -> false
        ......
    }
    //getReferrer(): android-app://com.***.filemanager
    log("getReferrer(): "+getReferrer());
    mReferrerFillInIntent = new Intent()
        .putExtra(Intent.EXTRA_REFERRER, getReferrer());

    mChosenComponentSender = intent.getParcelableExtra(
            Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER);
    mRefinementIntentSender = intent.getParcelableExtra(
            Intent.EXTRA_CHOOSER_REFINEMENT_INTENT_SENDER);
    //mChosenComponentSender: null
    log("mChosenComponentSender: "+mChosenComponentSender);
    //mRefinementIntentSender: null
    log("mRefinementIntentSender: "+mRefinementIntentSender);

    setSafeForwardingMode(true);

    pa = intent.getParcelableArrayExtra(
            Intent.EXTRA_EXCLUDE_COMPONENTS);
    if (pa != null) { // -> false
        ......
    }

    pa = intent.getParcelableArrayExtra(
            Intent.EXTRA_CHOOSER_TARGETS);
    if (pa != null) { // -> false
        ......
    }
    /*
     * prefsFile: 
     * /data/user/0/android/shared_prefs/chooser_pin_settings.xml
     */
    mPinnedSharedPrefs = getPinnedSharedPrefs(this);
    setRetainInOnStop(intent
        .getBooleanExtra(EXTRA_PRIVATE_RETAIN_IN_ON_STOP, false));
    /*
     * 进入父类的onCreate()方法
     */
    super.onCreate(savedInstanceState, target, 
            title, defaultTitleRes, initialIntents,
            null, false);

    MetricsLogger.action(this, 
        MetricsEvent.ACTION_ACTIVITY_CHOOSER_SHOWN);

    mChooserShownTime = System.currentTimeMillis();
    final long systemCost = mChooserShownTime - intentReceivedTime;
    MetricsLogger.histogram(null, 
        "system_cost_for_smart_sharing", (int) systemCost);
    if (DEBUG) {
        //System Time Cost is 298 花费了300ms,还是慢
        Log.d(TAG, "System Time Cost is " + systemCost);
    }
}

下面进入父类ResolverActivity类的onCreate()方法。

protected void onCreate(Bundle savedInstanceState, 
        Intent intent,CharSequence title, int defaultTitleRes, 
        Intent[] initialIntents,List<ResolveInfo> rList, 
        boolean supportsAlwaysUseOption) {
    setTheme(R.style.Theme_DeviceDefault_Resolver);
    super.onCreate(savedInstanceState);
    log("method onCreate() 7 params");
    isFromScreenShot = getIntent()
        .getBooleanExtra("screen_shot", false);
    // Determine whether we should show that intent 
    // is forwarded from managed profile to owner or
    // other way around.
    setProfileSwitchMessageId(intent.getContentUserHint());

    try {
        mLaunchedFromUid = ActivityManager.getService()
            .getLaunchedFromUid(getActivityToken());
    } catch (RemoteException e) {
        mLaunchedFromUid = -1;
    }
    //mLaunchedFromUid: 10044
    log("mLaunchedFromUid: "+mLaunchedFromUid);
    if (mLaunchedFromUid < 0 
        || UserHandle.isIsolated(mLaunchedFromUid)) {// -> false
        // Gulp!
        finish();
        return;
    }

    mPm = getPackageManager();

    mPackageMonitor.register(this, getMainLooper(), false);
    mRegistered = true;
    mReferrerPackage = getReferrerPackageName();
    mSupportsAlwaysUseOption = supportsAlwaysUseOption;
    //com.***.filemanager
    log("mReferrerPackage: "+mReferrerPackage);
    //false
    log("mSupportsAlwaysUseOption: "+mSupportsAlwaysUseOption);

    final ActivityManager am = 
            (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    mIconDpi = am.getLauncherLargeIconDensity();
    //320
    log("mIconDpi: "+mIconDpi);
    // Add our initial intent as the first item, regardless
    // of what else has already been added.
    mIntents.add(0, new Intent(intent));
    mTitle = title;
    mDefaultTitleResId = defaultTitleRes;
    /*
     * 先进入configureContentView()方法
     */
    if (configureContentView(mIntents, initialIntents, rList)) {
        log("configureContentView return true");
        return;
    }

    final ResolverDrawerLayout rdl = findViewById(R.id.contentPanel);
    if (rdl != null) { // -> true
        log("rdl: "+rdl);
        rdl.setOnDismissedListener(new ResolverDrawerLayout
            .OnDismissedListener() {
            @Override
            public void onDismissed() {
                finish();
            }
        });
        if (isVoiceInteraction()) {
            rdl.setCollapsed(false);
        }
        mResolverDrawerLayout = rdl;
    }

    mProfileView = findViewById(R.id.profile_button);
    if (mProfileView != null) { // -> true
        log("mProfileView: "+mProfileView);
        mProfileView.setOnClickListener(new View
            .OnClickListener() {
            @Override
            public void onClick(View v) {
                final DisplayResolveInfo dri = mAdapter
                        .getOtherProfile();
                if (dri == null) {
                    return;
                }

                // Do not show the profile switch message
                // anymore.
                mProfileSwitchMessageId = -1;

                onTargetSelected(dri, false);
                finish();
            }
        });
        bindProfileView();
    }

    if (isVoiceInteraction()) {
        onSetupVoiceInteraction();
    }
    final Set<String> categories = intent.getCategories();
    MetricsLogger.action(this, mAdapter.hasFilteredItem()
            ? MetricsProto.MetricsEvent
                .ACTION_SHOW_APP_DISAMBIG_APP_FEATURED
            : MetricsProto.MetricsEvent
                .ACTION_SHOW_APP_DISAMBIG_NONE_FEATURED,
            intent.getAction() + ":" + intent.getType() + ":"
                    + (categories != null 
                    ? Arrays.toString(categories.toArray()) : ""));
    mIconFactory = IconDrawableFactory.newInstance(this, true);
}

下面进入ResolverActivity类的configureContentView()方法。

/**
 * Returns true if the activity is finishing and 
 * creation should halt
 */
public boolean configureContentView(List<Intent> payloadIntents, 
        Intent[] initialIntents,List<ResolveInfo> rList) {
    log("method configureContentView()");
    // The last argument of createAdapter is whether to do 
    // special handling of the last used choice to highlight 
    // it in the list.  We need to always turn this off when
    // running under voice interaction, since it results in
    // a more complicated UI that the current voice interaction
    // flow is not able to handle.
    /*
     * 这里实质调用的是子类ChooserActivity的createAdapter()方法
     * 先进入这里
     */
    mAdapter = createAdapter(this, payloadIntents, 
            initialIntents, rList,
            mLaunchedFromUid, 
            mSupportsAlwaysUseOption && !isVoiceInteraction());
    ......(省略一大段代码)
}

下面进入ChooserActivity类的createAdapter()方法。
这里创建了一个ChooserListAdapter对象,它继承于ResolveListAdapter。
前者是定义在ChooserActivity类中的内部类,后者是定义在ResolverActivity类中的内部类。

@Override
public ResolveListAdapter createAdapter(Context context, 
        List<Intent> payloadIntents,Intent[] initialIntents, 
        List<ResolveInfo> rList, int launchedFromUid,
        boolean filterLastUsed) {
    log("method createAdapter()");
    /*
     * 这个构造方法中就是一些简单的赋值操作
     */
    final ChooserListAdapter adapter = new ChooserListAdapter(
            context, payloadIntents,initialIntents, rList,
            launchedFromUid, filterLastUsed, 
            createListController());
    return adapter;
}

下面回到ResolverActivity类的configureContentView()方法。

public boolean configureContentView(List<Intent> payloadIntents, 
        Intent[] initialIntents,List<ResolveInfo> rList) {
    ......
    //这里实质调用的是子类的createAdapter()方法。
    //执行完了
    mAdapter = createAdapter(this, payloadIntents, 
            initialIntents, rList,
            mLaunchedFromUid, 
            mSupportsAlwaysUseOption && !isVoiceInteraction());
     /*
      * 进入这里
      * 这里实质调用的是ResolveListAdapter的rebuildList()方法。
      */
    boolean rebuildCompleted = mAdapter.rebuildList();
    // false
    log("rebuildCompleted: "+rebuildCompleted);

    if (useLayoutWithDefault()) { // -> false
        log("use default layout");
        mLayoutId = R.layout.resolver_list_with_default;
    } else {
        mLayoutId = getLayoutResource();
    }
    setContentView(mLayoutId);

    int count = mAdapter.getUnfilteredCount();
    // 0
    log("count: "+count);

    // We only rebuild asynchronously when we have multiple
    // elements to sort. In the case where
    // we're already done, we can check if we should
    // auto-launch immediately.
    if (rebuildCompleted) { // -> false
        ......
    }

    mAdapterView = findViewById(R.id.resolver_list);

    if (count == 0 && mAdapter.mPlaceholderCount == 0) {// -> false
        log("show empth view");
        final TextView emptyView = findViewById(R.id.empty);
        emptyView.setVisibility(View.VISIBLE);
        mAdapterView.setVisibility(View.GONE);
    } else {// get in
       mAdapterView = findViewById(R.id.resolver_list);
        //显示ListView
        mAdapterView.setVisibility(View.VISIBLE);
        //实质调用子类的onPrepareAdapterView()方法
        onPrepareAdapterView(mAdapterView, mAdapter);
    }
    return false;
}

下面进入ResolveListAdapter类的rebuildList()方法。

/**
 * Rebuild the list of resolvers. In some cases some parts
 * will need some asynchronous work
 * to complete.
 *
 * @return Whether or not the list building is completed.
 */
protected boolean rebuildList() {
    log("method rebuildList()");
    List<ResolvedComponentInfo> currentResolveList = null;
    // Clear the value of mOtherProfile from previous call.
    mOtherProfile = null;
    mLastChosen = null;
    mLastChosenPosition = -1;
    mDisplayList.clear();
    // null 
    log("mBaseResolveList: "+mBaseResolveList);
    if (mBaseResolveList != null) { // -> false
        currentResolveList = mUnfilteredResolveList = new ArrayList<>();
        mResolverListController.addResolveListDedupe(
                currentResolveList,
                getTargetIntent(),
                mBaseResolveList);
    } else {
        /*
         * 重点! 
         * 这里查询符合Intent分享条件的app
         * mResolverListController是ResolverListController对象
         * 进入这个方法
         */
        currentResolveList = mUnfilteredResolveList =
             mResolverListController
                .getResolversForIntent(shouldGetResolvedFilter(),
                    shouldGetActivityMetadata(),mIntents);
        if (currentResolveList == null) {// -> false
            processSortedList(currentResolveList);
            return true;
        }
        List<ResolvedComponentInfo> originalList =
               mResolverListController
              .filterIneligibleActivities(currentResolveList,
                        true);
        // null
        log("originalList: "+originalList);
        if (originalList != null) {
            mUnfilteredResolveList = originalList;
        }
    }

    ......

    int N;
    if ((currentResolveList != null) 
        && ((N = currentResolveList.size()) > 0)) {
        // 4
        log("N: "+N);
        // We only care about fixing the unfilteredList
        // if the current resolve list and
        // current resolve list are currently the same.
        List<ResolvedComponentInfo> originalList =
                mResolverListController
                    .filterLowPriority(currentResolveList,
                        mUnfilteredResolveList == currentResolveList);
        // null
        log("originalList: "+originalList);
        if (originalList != null) {
            mUnfilteredResolveList = originalList;
        }

        if (currentResolveList.size() > 1) {
            int placeholderCount = currentResolveList.size();
            if (useLayoutWithDefault()) {// -> false
                --placeholderCount;
            }
            // 4
            log("placeholderCount: "+placeholderCount);
            setPlaceholderCount(placeholderCount);
            AsyncTask<List<ResolvedComponentInfo>,
                    Void,
                    List<ResolvedComponentInfo>> sortingTask =
                    new AsyncTask<List<ResolvedComponentInfo>,
                            Void,
                            List<ResolvedComponentInfo>>() {
                @Override
                protected List<ResolvedComponentInfo> doInBackground(
                        List<ResolvedComponentInfo>... params) {
                    mResolverListController.sort(params[0]);
                    return params[0];
                }

                @Override
                protected void onPostExecute(
                    List<ResolvedComponentInfo> sortedComponents) {
                    processSortedList(sortedComponents);
                    if (mProfileView != null) {
                        bindProfileView();
                    }
                    notifyDataSetChanged();
                }
            };
            log("start to execute sorting task");
            //执行排序的异步任务
            sortingTask.execute(currentResolveList);
            /*
             * 进入这里
             */
            postListReadyRunnable();
            return false;
        } else {
            processSortedList(currentResolveList);
            return true;
        }
    } else {
        processSortedList(currentResolveList);
        return true;
    }
}

下面进入ResolverListController类的getResolversForIntent()方法。

@VisibleForTesting
public List<ResolverActivity.ResolvedComponentInfo> 
    getResolversForIntent(
        boolean shouldGetResolvedFilter,
        boolean shouldGetActivityMetadata,
        List<Intent> intents) {
    log("method getResolversForIntent()");
    // true
    log("shouldGetResolvedFilter: "+shouldGetResolvedFilter);
    // true
    log("shouldGetActivityMetadata: "+shouldGetActivityMetadata);
    // 1
    log("intents: "+intents.size());

    List<ResolverActivity.ResolvedComponentInfo> resolvedComponents = null;
    for (int i = 0, N = intents.size(); i < N; i++) {
        final Intent intent = intents.get(i);
        /*index: 0 intent: Intent { act=android.intent.action.SEND
        typ=application/vnd.android.package-archive
        flg=0x8080003 clip={application/vnd.android.package-archive
        U:content://com.***.filemanager.fileProvider
        /external_storage/demo.apk}(has extras) }*/
        log("index: "+i+" intent: "+intent);
        /*
         * 这里使用PackageManager查询符合Intent条件的app
         */
        final List<ResolveInfo> infos = mpm.queryIntentActivities(
           intent,PackageManager.MATCH_DEFAULT_ONLY
           | (shouldGetResolvedFilter 
              ? PackageManager.GET_RESOLVED_FILTER : 0)
           | (shouldGetActivityMetadata 
              ? PackageManager.GET_META_DATA : 0)
           | PackageManager.MATCH_INSTANT);
        // Remove any activities that are not exported.
        int totalSize = infos.size();
        for (int j = totalSize - 1; j >= 0 ; j--) {
            ResolveInfo info = infos.get(j);
            if (info.activityInfo != null 
                && !info.activityInfo.exported) {
                infos.remove(j);
            }
        }
        if (infos != null) {
            if (resolvedComponents == null) {
                resolvedComponents = new ArrayList<>();
            }
            addResolveListDedupe(resolvedComponents, 
                intent, infos);
        }
    }
    //当前查询出来有4个app符合
    log("resolvedComponents: "+resolvedComponents);
    return resolvedComponents;
}

当getResolversForIntent()这个方法执行完成以后回到rebuildList()方法。
回到rebuildList()方法后可以看见后续的流程启动了一个异步线程进行排序。
异步线程后紧接着进入ResolveListAdapter类的postListReadyRunnable()方法。

/**
 * Some necessary methods for creating the list are
 * initiated in onCreate and will also
 * determine the layout known. We therefore can't update
 * the UI inline and post to the
 * handler thread to update after the current task is finished.
 */
private void postListReadyRunnable() {
    log("method postListReadyRunnable()");
    if (mPostListReadyRunnable == null) {
        mPostListReadyRunnable = new Runnable() {
            @Override
            public void run() {
                /*
                 * 这个run方法将会运行在主线程中,因为当前主线程
                 * 正在运行onCreate()流程,所以当onCreate()流程
                 * 执行完成以后才会这个runnable。
                 */
                log("mPostListReadyRunnable run doing......");
                setTitleAndIcon();
                resetAlwaysOrOnceButtonBar();
                //这里的实质又是调用子类的onListRebuilt()方法
                log("use son class method: onListRebuilt()");
                onListRebuilt();
                mPostListReadyRunnable = null;
            }
        };
        getMainThreadHandler().post(mPostListReadyRunnable);
    }
}

下面回到ResolverActivity的configureContentView()方法。

public boolean configureContentView(List<Intent> payloadIntents,
        Intent[] initialIntents,
        List<ResolveInfo> rList) {
    log("method configureContentView()");
    // The last argument of createAdapter is whether to
    // do special handling of the last used choice to
    // highlight it in the list. We need to always
    // turn this off when running under voice interaction,
    // since it results in a more complicated UI that the
    // current voice interaction flow is not able to handle.
    //这里实质调用的是子类的createAdapter()方法。
    mAdapter = createAdapter(this, payloadIntents,
            initialIntents, rList,
            mLaunchedFromUid, 
            mSupportsAlwaysUseOption && !isVoiceInteraction());
    boolean rebuildCompleted = mAdapter.rebuildList();
    // false
    log("rebuildCompleted: "+rebuildCompleted);

    if (useLayoutWithDefault()) { // -> false
        log("use default layout");
        mLayoutId = R.layout.resolver_list_with_default;
    } else {
        mLayoutId = getLayoutResource();
    }
    setContentView(mLayoutId);

    int count = mAdapter.getUnfilteredCount();
    // 0
    log("count: "+count);

    // We only rebuild asynchronously when we have
    // multiple elements to sort. In the case where
    // we're already done, we can check if we should
    // auto-launch immediately.
    if (rebuildCompleted) { // -> false
        ......
    }

    mAdapterView = findViewById(R.id.resolver_list);

    if (count == 0 && mAdapter.mPlaceholderCount == 0) {// -> false
        log("show empth view");
        final TextView emptyView = findViewById(R.id.empty);
        emptyView.setVisibility(View.VISIBLE);
        mAdapterView.setVisibility(View.GONE);
    } else {// get in
        log("get in else");
       mAdapterView = findViewById(R.id.resolver_list);
        //显示ListView
        mAdapterView.setVisibility(View.VISIBLE);
        /*
         * 实质调用子类的onPrepareAdapterView()方法
         */
        onPrepareAdapterView(mAdapterView, mAdapter);
    }
    return false;
}

下面进入ChooserActivity类的onPrepareAdapterView()方法。

@Override
public void onPrepareAdapterView(AbsListView adapterView,
        ResolveListAdapter adapter) {
    final ListView listView = 
        adapterView instanceof ListView 
        ? (ListView) adapterView : null;
    mChooserListAdapter = (ChooserListAdapter) adapter;
    if (mCallerChooserTargets != null 
        && mCallerChooserTargets.length > 0) { // -> false
        mChooserListAdapter.addServiceResults(null,
        Lists.newArrayList(mCallerChooserTargets));
    }
    /*
     * 这里构建的才是我们真正ListView使用的Adapter,它
     * 直接继承自BaseAdapter
     * 其ListView的item的click响应事件是在Adapter中进行设置的
     */
    mChooserRowAdapter = new ChooserRowAdapter(mChooserListAdapter);
    mChooserRowAdapter.registerDataSetObserver(
        new OffsetDataSetObserver(adapterView));
    adapterView.setAdapter(mChooserRowAdapter);
    log("listView: "+listView);
    if (listView != null) {
        listView.setItemsCanFocus(true);
    }
}

至此父类和子类的onCreate()方法都执行完成了。
当主线程其它流程执行完成以后就开始执行我们当设置的postListReadyRunnable()方法。
postListReadyRunnable()方法主要就是查询符合分享条件的应用还需不需要启动各自分享的service。
其核心是onListRebuilt()方法。这里将会调用子类ChooserListAdapter的onListRebuilt()方法。

至此分享的界面就显示在手机的界面上了。

点击Click事件

下面进入ChooserRowAdapter类中item的click点击事件流程。

@Override
public View getView(int position, View convertView,
        ViewGroup parent) {
    final RowViewHolder holder;
    if (convertView == null) {
        holder = createViewHolder(parent);
    } else {
        holder = (RowViewHolder) convertView.getTag();
    }
    bindViewHolder(position, holder);

    return holder.row;
}

RowViewHolder createViewHolder(ViewGroup parent) {
    final ViewGroup row = (ViewGroup) mLayoutInflater
        .inflate(R.layout.chooser_row,parent, false);
    final RowViewHolder holder = new RowViewHolder(row,
            mColumnCount);
    final int spec = MeasureSpec.makeMeasureSpec(0, 
            MeasureSpec.UNSPECIFIED);

    for (int i = 0; i < mColumnCount; i++) {
        final View v = mChooserListAdapter.createView(row);
        final int column = i;
        v.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                 * 点击事件进入这里
                 */
                log("onClick: "+column);
                startSelected(holder.itemIndices[column],
                    false, true);
            }
        });
        v.setOnLongClickListener(new OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                log("onLongClick: "+column);
                showTargetDetails(mChooserListAdapter
                    .resolveInfoForPosition(
                        holder.itemIndices[column], true));
                return true;
            }
        });
        row.addView(v);
        holder.cells[i] = v;

        // Force height to be a given so we don't
        // have visual disruption during scaling.
        LayoutParams lp = v.getLayoutParams();
        v.measure(spec, spec);
        if (lp == null) {
            lp = new LayoutParams(LayoutParams.MATCH_PARENT,
                v.getMeasuredHeight());
            row.setLayoutParams(lp);
        } else {
            lp.height = v.getMeasuredHeight();
        }
        if (i != (mColumnCount - 1)) {
            row.addView(new Space(ChooserActivity.this),
                    new LinearLayout.LayoutParams(0, 0, 1));
        }
    }

    // Pre-measure so we can scale later.
    holder.measure();
    LayoutParams lp = row.getLayoutParams();
    if (lp == null) {
        lp = new LayoutParams(LayoutParams.MATCH_PARENT,
            holder.measuredRowHeight);
        row.setLayoutParams(lp);
    } else {
        lp.height = holder.measuredRowHeight;
    }
    row.setTag(holder);
    return holder;
}

下面进入ChooserActivity类的startSelected()方法。

@Override
public void startSelected(int which, boolean always,
    boolean filtered) {
    log("method startSelected()");
    final long selectionCost = 
        System.currentTimeMillis() - mChooserShownTime;
    //调用父类的了
    super.startSelected(which, always, filtered);
    ......
}

下面进入父类的ResolverActivity的startSelected()方法。

public void startSelected(int which, boolean always,
    boolean hasIndexBeenFiltered) {
    log("method startSelected()");
    if (isFinishing()) {
        return;
    }
    ResolveInfo ri = mAdapter
        .resolveInfoForPosition(which, hasIndexBeenFiltered);
    /*ResolveInfo{45cfa38 com.android.bluetooth/
    .opp.BluetoothOppLauncherActivity m=0x608000}*/
    log("ri: "+ri);
    if (mResolvingHome && hasManagedProfile() 
        && !supportsManagedProfiles(ri)) {
        Toast.makeText(this, String.format(getResources()
            .getString(com.android.internal.
                R.string.activity_resolver_work_profiles_support),
                ri.activityInfo.loadLabel(getPackageManager()).toString()),
                Toast.LENGTH_LONG).show();
        return;
    }

    TargetInfo target = mAdapter
        .targetInfoForPosition(which, hasIndexBeenFiltered);
    /*com.android.internal.app
    .ResolverActivity$DisplayResolveInfo@f23ca11*/
    log("target: "+target);
    if (target == null) {
        return;
    }
    /*
     * 进入这里
     */
    if (onTargetSelected(target, always)) {
        if (always && mSupportsAlwaysUseOption) {
            MetricsLogger.action(
                    this, MetricsProto.MetricsEvent
                          .ACTION_APP_DISAMBIG_ALWAYS);
        } else if (mSupportsAlwaysUseOption) {
            MetricsLogger.action(
                    this, MetricsProto.MetricsEvent
                          .ACTION_APP_DISAMBIG_JUST_ONCE);
        } else {
            MetricsLogger.action(
                    this, MetricsProto.MetricsEvent
                          .ACTION_APP_DISAMBIG_TAP);
        }
        MetricsLogger.action(this, mAdapter.hasFilteredItem()
                        ? MetricsProto.MetricsEvent
                            .ACTION_HIDE_APP_DISAMBIG_APP_FEATURED
                        : MetricsProto.MetricsEvent
                            .ACTION_HIDE_APP_DISAMBIG_NONE_FEATURED);
        finish();
    }
}

下面进入ResolverActivity的onTargetSelected()方法。

protected boolean onTargetSelected(TargetInfo target, 
    boolean alwaysCheck) {
    /* com.android.internal.app
    .ResolverActivity$DisplayResolveInfo@f23ca11*/
    log("target: "+target);
    //false
    log("alwaysCheck: "+alwaysCheck);
    final ResolveInfo ri = target.getResolveInfo();
    final Intent intent = target != null 
        ? target.getResolvedIntent() : null;
    // -> false
    if (intent != null && (mSupportsAlwaysUseOption 
            || mAdapter.hasFilteredItem())
            && mAdapter.mUnfilteredResolveList != null) {

        ......(省略一大段代码)
    }

    if (target != null) {//-> true
        safelyStartActivity(target);
    }
    return true;
}

下面进入ResolverActivity的safelyStartActivity()方法。

public void safelyStartActivity(TargetInfo cti) {
    log("method safelyStartActivity()");
    // We're dispatching intents that might be coming
    // from legacy apps, so don't kill ourselves.
    StrictMode.disableDeathOnFileUriExposure();
    try {
        safelyStartActivityInternal(cti);
    } finally {
        StrictMode.enableDeathOnFileUriExposure();
    }
}

private void safelyStartActivityInternal(TargetInfo cti) {
    log("method safelyStartActivityInternal()");
    /*com.android.internal.app
    .ResolverActivity$DisplayResolveInfo*/
    log("cti: "+cti.getClass().getName());
    // If needed, show that intent is forwarded
    // from managed profile to owner or other way around.
    if (mProfileSwitchMessageId != -1) {
        Toast.makeText(this, 
        getString(mProfileSwitchMessageId), 
        Toast.LENGTH_LONG).show();
    }
    // true
    log("mSafeForwardingMode: " + mSafeForwardingMode);
    if (!mSafeForwardingMode) {
        if (cti.start(this, null)) {
            onActivityStarted(cti);
        }
        return;
    }
    try {
        /*
         * 这里是启动启动activity的动作
         */
         * @Override
         *  public boolean startAsCaller(Activity activity, 
         *     Bundle options, int userId) {
         *      activity.startActivityAsCaller(mResolvedIntent,
         *         options, false, userId);
         *      return true;
         *  }
         *
         */
        // -> true
        if (cti.startAsCaller(this, null, UserHandle.USER_NULL)) {
            log("start as caller");
            /*
              * 这个方法是设置activity启动后的结果
              * 其实质是调用子类的onActivityStarted()
              */
            onActivityStarted(cti);
        }
    } catch (RuntimeException e) {
        String launchedFromPackage;
        try {
            launchedFromPackage = ActivityManager
            qq.getService().getLaunchedFromPackage(
                    getActivityToken());
        } catch (RemoteException e2) {
            launchedFromPackage = "??";
        }
        Slog.wtf(TAG, "Unable to launch as uid " 
                + mLaunchedFromUid
                + " package " + launchedFromPackage 
                + ", while running in "
                + ActivityThread.currentProcessName(), e);
    }
}

下面进入ChooserActivity类的onActivityStarted()方法。

@Override
public void onActivityStarted(TargetInfo cti) {
    log("method onActivityStarted()");
    log("mChosenComponentSender: "+mChosenComponentSender);
    /*
     * mChosenComponentSender是
     * Intent.EXTRA_CHOSEN_COMPONENT_INTENT_SENDER获得
     */
    if (mChosenComponentSender != null) {// ->false
        final ComponentName target = 
            cti.getResolvedComponentName();
        if (target != null) {
            final Intent fillIn = new Intent()
                .putExtra(Intent.EXTRA_CHOSEN_COMPONENT, target);
            try {
                mChosenComponentSender.sendIntent(this, 
                    Activity.RESULT_OK, fillIn, null, null);
            } catch (IntentSender.SendIntentException e) {
                Slog.e(TAG, "Unable to launch supplied"
                    + "IntentSender to report "
                    + "the chosen component: " + e);
            }
        }
    }
}

一个完成调用系统分享的执行过程就分析完成了。