resolveActivity是Activity创建过程中非常重要的一个函数,会在ActivityStackstartActivityMayWait中调用。这个函数的主要作用就是根据intent去收集需要启动的activity的信息,看下函数的原型:

   ActivityInfo resolveActivity(Intent intent, String resolvedType, boolean debug,           String profileFile, ParcelFileDescriptor profileFd, boolean autoStopProfiler) {       // 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);           aInfo = rInfo != null ? rInfo.activityInfo : null;       } catch (RemoteException e) {           aInfo = null;       }   if (aInfo != null) {       // Store the found target back into the intent, because now that       // we have it we never want to do this again.  For example, if the       // user navigates back to this point in the history, we should       // always restart the exact same activity.       intent.setComponent(new ComponentName(               aInfo.applicationInfo.packageName, aInfo.name));       // Don't debug things in the system process       if (debug) {           if (!aInfo.processName.equals("system")) {               mService.setDebugApp(aInfo.processName, true, false);           }       }       if (profileFile != null) {           if (!aInfo.processName.equals("system")) {               mService.setProfileApp(aInfo.applicationInfo, aInfo.processName,                       profileFile, profileFd, autoStopProfiler);           }       }   }   return aInfo;

}
为了不影响对resolveActivity的分析,需要把Activity启动过程中传到此函数的参数说明一下,当我们点击launcher界面启动一个Activity的时候,intent就是我们正常启动启动Activity时的intent;其余的boolean类型的值为false,非boolean类型的值为null。
函数的关键在AppGlobals.getPackageManager().resolveIntent(intent, resolvedType, PackageManager.MATCH_DEFAULT_ONLY | ActivityManagerService.STOCK_PM_FLAGS)。AppGlobals这个变量提供了一个静态方法,方便应用可以获取系统的函数调用接口。最重要的部分应该就是getPackageManager().resolveInten了,ok,到PackageManagerService看下resolveIntent这个方法。

   public ResolveInfo resolveIntent(Intent intent, String resolvedType,           int flags) {       List query = queryIntentActivities(intent, resolvedType, flags);       return chooseBestActivity(intent, resolvedType, flags, query);   }  

resolveIntent经过了两个步骤,首先根据传递的信息选出符合条件的集合,然后从集合中找出最合适的信息。第一步queryIntentActivities根据intent, resolveType,flag信息选出可能存在的Activity的信息;chooseBestActivity会从第一步的信息的集合中选择最符合条件的Activity,如果chooseBestActivity选出的符合条件的Activity不止一个,则会让用户选择具体需要启动哪个Activity。可以看下chooseBestActivity的实现:

   private ResolveInfo chooseBestActivity(Intent intent, String resolvedType,                                          int flags, List query) {       if (query != null) {           final int N = query.size();           /**如果根据条件只找到了一个Activity,则直接返回*/           if (N == 1) {               return query.get(0);           } else if (N > 1) {               /**根据条件找到了多个Activity*/               // 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);               }               /**如果第一个Activity有更高的优先级,或者default设置不相同,则返回第一个Activity*/               // 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);               if (ri != null) {                   return ri;               }               return mResolveInfo;           }       }       return null;   }

多有多个Activity符合查询条件时,最终会进入findPreferredActivity找到最合适的Activity。findPreferredActivity最终会调用findPersistentPreferredActivityLP这个函数。 由于正在分析Activity的启动流程,这个函数我还没有去分析,个人猜想可能是这样一个流程,类似于我们在android上打开一个网页,如果你有多个浏览器可以去打开网页,那么android弹出对话框,让用户选择使用哪个浏览器去打开网页;如果用户选择了一个浏览器并且勾选了总是,那么下次再打开网页的时候就会启动已经默认的浏览器,如果用户没有勾选总是,则每次打开网页的时候就会弹出对话框让用户选择。

更多相关文章

  1. [android] android下文件访问的权限
  2. 基于Android的Linux内核的电源管理:Early Suspend
  3. Android(安卓)技巧 - 取得当前活动的activity的class name / pac
  4. Android用户登录数据存储的三种方式
  5. Android(安卓)游戏开发中 OnTouchEvent() 触屏事件的性能优化
  6. React Native项目组织结构介绍
  7. Android控制ScrollView滚动
  8. Android(安卓)camera系统开发之IPC (五)
  9. 深拷贝和浅拷贝

随机推荐

  1. Android 学习资料收集汇总
  2. [Android]APK程序卸载二次确认的实现
  3. android开发打印票据或文档的方法:android
  4. Android 小項目之--猜名字有獎!RadionButt
  5. 关于android图片的传输,android图片传输方
  6. android中发生OOM探究及解决
  7. Unity3D For Android 开发教程【转http:/
  8. Android(安卓)Things学习的一点体验
  9. Android Q (十七) Android Q 行为变更:以
  10. android 图片处理 (滤镜,图片位置)