ResolverActivity / ChooserActivity的联系与区别

本文详细介绍了Android中ResolverActivity的逻辑,包括用户选择始终后的行为,涉及PackageManagerService的addPreferredActivity方法。同时,对比了ChooserActivity缺少仅一次和始终选项的特性。此外,探讨了系统和应用中ResolverActivity的运行进程,以及选择目标后如何通过ActivityTaskManagerService启动活动。整个流程涵盖了跨进程通信和Activity启动的关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. ResolverActivity 提供 “仅一次” 和“始终选项”。

选择了始终后的逻辑

ResolverActivity.onTargetSelected
 pm.addUniquePreferredActivity(filter, bestMatch, set, intent.getComponent())

pm = getPackageManager(); //实际上是ApplicationPackageManager实例, 封装了真正的PMS

-> ContextImpl. getPackageManager() 
         pm = ActivityThread.getPackageManager(); //binder PMS
pm = mPackageManager = new ApplicationPackageManager(this, pm)

ApplicationPackageManager
mPM.addPreferredActivity(filter, match, set, activity, getUserId(), false);// PMS

//真正实现
PackageManagerService
addPreferredActivity(WatchedIntentFilter filter, int match,
            ComponentName[] set, ComponentName activity, boolean always, int userId,
            String opname, boolean removeExisting) {

2. ChooserActivity 继承了 ResolverActivity,

但是没有了  “仅一次” 和“始终选项” 这两个选项, 因此每一次都会弹出来选择。

public class ChooserActivity extends ResolverActivity implements
        ChooserListAdapter.ChooserListCommunicator,
        SelectableTargetInfoCommunicator {

3. 系统弹出来的 chooseractivity,

例如相册分享,它是运行在 android:ui 进程上

4. 一些应用弹出来的 resolveractivity

例如nfc 选择支付,它是运行在 com.android.nfc 进程上

5. 选择后, 调用了 ActivityTaskManagerService.startActivity/startActivityAsUser 启动

当然,先会跑resolveracitivity里的点击响应操作,调用栈如下:

onTargetSelected:1630, ResolverActivity (com.android.internal.app)
onTargetSelected:1435, ResolverActivity (com.android.internal.app)
startSelected:1324, ResolverActivity (com.android.internal.app)
onItemClick:2753, ResolverActivity$ItemClickListener (com.android.internal.app)
performItemClick:376, AdapterView (android.widget)
performItemClick:1282, AbsListView (android.widget)
run:3558, AbsListView$PerformClick (android.widget)

ResolverActivity 
-safelyStartActivityAsUser
-- safelyStartActivityInternal(TargetInfo cti, UserHandle user)

----> cti.startAsUser(this, null, user) 或者  cti.startAsCaller(this, null, tUserId) (两种)
接口TargetInfo 由 MultiDisplayResolveInfo实现,

然后调用 DisplayResolveInfo.startAsUserstartAsCaller
接着调用 activity.startActivityAsUser / startActivityAsCaller(mResolvedIntent, options, false, userId);
这里之后就是跨进程通信, app 通过 AIDL/Binder 调用 ActivityTaskManagerService startActivityAsUser / startActivity (system_server (wms))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值