android 4.1 JellyBean 跟踪应用程序选择框弹出流程
2012-09-26 20:59
344 查看
一:简述
在android中,如果一个intent可以被多个activity匹配那么,ActivityManagerSevice(AMS)会启动一个应用程序选择框供用户选择使用那个activity来执行这个Intent。比如,如果手机里面装有两个图片显示activity,可以执行图片显示的Intent。显示图片的intent发出后,我们会看到有一个弹出框列出了相关的activity供用户选择。
二:代码流程
根据activity的启动过程,startActivity的intent发出后,该信息会由AMS接收并解析。解析完后得到该activity的详细信息,然后调用该activity的组建启动。这个启动过程网上有很多介绍,这里就不赘述了。本文主要讨论那个多应用程序选择框的弹出机制。
1. AMS处理的相关代码如下,位于:frameworks/base/services/java/com/android/server/am/ActivityStack.java
系统中,启动activity的intent都是在这里加工,转换成需要的ActivityInfo的。重要的调用函数是resolveActivity(intent, resolvedType, startFlags, profileFile, profileFd, userId);
这就是Intent信息到Activity信息的匹配过程。
2.这个匹配信息是怎么来的呢,根据下面的resolveActivity函数代码,我们知道,所有这些信息保存在PackageManagerService(PMS)中。PMS中的信息是activity在装载到手机上的时候保存的。找到就返回,否则返回null。
3.接下载自然是去PackageManagerService里面查找resolveIntent函数了。
这里面调用一个queryIntentActivities函数,返回可以匹配该intent的所有activity列表。然后,PMS接着调用chooseBestActivity函数,选择最佳activity,然后返回。
4.最佳activity选择过程
这里,如果只有一个activty匹配,那么直接返回该acivity的ResolveInfo。如果选择出来的activity大于一个,那么会挑出前两个进行比较,默认情况下优先级、preferredOrder和isDefault都是一样的。本函数返回mResolveInfo。该resolveinfo包含一个叫做ResolveActivity的activity信息。把这个信息返回给AMS去启动,那就变成启动这个activity了。这个activity是一个AlerActivity,它收集和显示匹配的所有activity信息,供用户选择。
5.再者,选择框中,如果用户选择了某个应用程序,而且指定永久使用该activity来执行相关intent,这时候,系统也是会跑上面的流程,只不过在findPreferredActivity函数中做进一步处理。
6.findPreferredActivity的主要工作原理是:在setting里面保存着一个用户勾选过的mPreferredActivities列表,然后比较是否传入的参数是否在mPreferredActivities中。
List<PreferredActivity> prefs =
mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
在android中,如果一个intent可以被多个activity匹配那么,ActivityManagerSevice(AMS)会启动一个应用程序选择框供用户选择使用那个activity来执行这个Intent。比如,如果手机里面装有两个图片显示activity,可以执行图片显示的Intent。显示图片的intent发出后,我们会看到有一个弹出框列出了相关的activity供用户选择。
二:代码流程
根据activity的启动过程,startActivity的intent发出后,该信息会由AMS接收并解析。解析完后得到该activity的详细信息,然后调用该activity的组建启动。这个启动过程网上有很多介绍,这里就不赘述了。本文主要讨论那个多应用程序选择框的弹出机制。
1. AMS处理的相关代码如下,位于:frameworks/base/services/java/com/android/server/am/ActivityStack.java
final int startActivityMayWait(IApplicationThread caller, int callingUid, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, String profileFile, ParcelFileDescriptor profileFd, WaitResult outResult, Configuration config, Bundle options, int userId) { // Refuse possible leaked file descriptors if (intent != null && intent.hasFileDescriptors()) { throw new IllegalArgumentException("File descriptors passed in Intent"); } boolean componentSpecified = intent.getComponent() != null; // Don't modify the client's object! intent = new Intent(intent); // Collect information about the target of the Intent. ActivityInfo aInfo = resolveActivity(intent, resolvedType, startFlags, profileFile, profileFd, userId); if (aInfo != null && mService.isSingleton(aInfo.processName, aInfo.applicationInfo)) { userId = 0; } aInfo = mService.getActivityInfoForUser(aInfo, userId); ..... }
系统中,启动activity的intent都是在这里加工,转换成需要的ActivityInfo的。重要的调用函数是resolveActivity(intent, resolvedType, startFlags, profileFile, profileFd, userId);
这就是Intent信息到Activity信息的匹配过程。
2.这个匹配信息是怎么来的呢,根据下面的resolveActivity函数代码,我们知道,所有这些信息保存在PackageManagerService(PMS)中。PMS中的信息是activity在装载到手机上的时候保存的。找到就返回,否则返回null。
ActivityInfo resolveActivity(Intent intent, String resolvedType, int startFlags, String profileFile, ParcelFileDescriptor profileFd, int userId) { // Collect information about the target of the Intent. ActivityInfo aInfo; try { ResolveInfo rInfo = AppGlobals.getPackageManager().resolveIntent( intent, resolvedType, PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS, userId); aInfo = rInfo != null ? rInfo.activityInfo : null; } catch (RemoteException e) { aInfo = null; } 。。。。 }
3.接下载自然是去PackageManagerService里面查找resolveIntent函数了。
public ResolveInfo resolveIntent(Intent intent, String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return null; List<ResolveInfo> query = queryIntentActivities(intent, resolvedType, flags, userId); return chooseBestActivity(intent, resolvedType, flags, query, userId); }
这里面调用一个queryIntentActivities函数,返回可以匹配该intent的所有activity列表。然后,PMS接着调用chooseBestActivity函数,选择最佳activity,然后返回。
4.最佳activity选择过程
private ResolveInfo chooseBestActivity(Intent intent, String resolvedType, int flags, List<ResolveInfo> query, int userId) { if (query != null) { final int N = query.size(); if (N == 1) { return query.get(0); } else if (N > 1) { // If there is more than one activity with the same priority, // then let the user decide between them. ResolveInfo r0 = query.get(0); ResolveInfo r1 = query.get(1); if (DEBUG_INTENT_MATCHING) { Log.d(TAG, r0.activityInfo.name + "=" + r0.priority + " vs " + r1.activityInfo.name + "=" + r1.priority); } // If the first activity has a higher priority, or a different // default, then it is always desireable to pick it. if (r0.priority != r1.priority || r0.preferredOrder != r1.preferredOrder || r0.isDefault != r1.isDefault) { return query.get(0); } // If we have saved a preference for a preferred activity for // this Intent, use that. ResolveInfo ri = findPreferredActivity(intent, resolvedType, flags, query, r0.priority, userId); if (ri != null) { return ri; } return mResolveInfo; } } return null; }
这里,如果只有一个activty匹配,那么直接返回该acivity的ResolveInfo。如果选择出来的activity大于一个,那么会挑出前两个进行比较,默认情况下优先级、preferredOrder和isDefault都是一样的。本函数返回mResolveInfo。该resolveinfo包含一个叫做ResolveActivity的activity信息。把这个信息返回给AMS去启动,那就变成启动这个activity了。这个activity是一个AlerActivity,它收集和显示匹配的所有activity信息,供用户选择。
5.再者,选择框中,如果用户选择了某个应用程序,而且指定永久使用该activity来执行相关intent,这时候,系统也是会跑上面的流程,只不过在findPreferredActivity函数中做进一步处理。
6.findPreferredActivity的主要工作原理是:在setting里面保存着一个用户勾选过的mPreferredActivities列表,然后比较是否传入的参数是否在mPreferredActivities中。
List<PreferredActivity> prefs =
mSettings.mPreferredActivities.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0, userId);
相关文章推荐
- 如何解决放到android /system/app 下的应用程序无限重启弹出“异常终止”的问题
- Android----弹出框选择文件夹目录 以及启用新的Task打开文件
- android PopupWindow实现从底部弹出或滑出选择菜单或窗口
- Android弹出提示框数据进行选择
- android 下拉弹出框+地区选择三级联动
- android PopupWindow实现从底部弹出或滑出选择菜单或窗口
- Android 耳机插拔流程源码跟踪浅析
- Android 应用程序发布流程---碗豆荚发布流程
- android PopupWindow实现从底部弹出或滑出选择菜单或窗口
- Android Java应用程序调用跟踪
- android 点击EditText 弹出日期选择器DatePickerDialog
- Android Launcher启动应用程序流程源码解析
- Android 底部弹出Dialog(支付方式选择)
- 转 android 从底部弹出一个popuwindow,渐入渐出效果。我这里是用在购物车需要选择购买选项的操作。
- android弹出时间选择框
- android通过蓝牙接收文件打开时无法自动选择合适的应用程序
- android webview file标签点击弹出选择文件或拍照菜单
- Android弹出选项框及指示箭头动画选择
- framework启动流程之android应用程序
- Android 耳机插拔流程源码跟踪浅析