Android框架/系统服务是怎样管理第三方Search数据源的?
来源:互联网 发布:php 上传工具 编辑:程序博客网 时间:2024/05/22 13:10
如上一篇文章介绍(http://blog.csdn.net/zhanglianyu00/article/details/61196900 ),安卓search框架支持通过实现接口,将第三方App作为外部数据源接入到系统搜索。这篇文章看一下系统侧如何管理这些searchable info。
安卓框架层有一个SearchManager作为Search管理者的对外的接口。官方文档:https://developer.android.com/reference/android/app/SearchManager.html 。对应的系统服务是SearchManagerService.java。代码路径:frameworks/base/services/core/java/com/android/server/search。可以看到,是frameworks/base/services/core/java/com/android/server的一个子路径,可见SearchManagerService是系统核心服务之一,与PackageManagerService、ActivityManagerService地位等同。
在frameworks/base/services/core/java/com/android/server/search下只有两个文件:
Searchables.java SearchManagerService.java
SearchManagerService是系统服务类,实现了ISearchManager.stub接口。
Searchables定义了所有Searchable Activity的信息。
以某个App被安装/卸载的场景为例,看看SearchManagerService是怎么样维护Searchable info的。内部类MyPackageMonitor继承PackageMonitor:
/** * Refreshes the "searchables" list when packages are added/removed. */class MyPackageMonitor extends PackageMonitor { @Override public void onSomePackagesChanged() { updateSearchables(); } @Override public void onPackageModified(String pkg) { updateSearchables(); } private void updateSearchables() { final int changingUserId = getChangingUserId(); synchronized (mSearchables) { // Update list of searchable activities for (int i = 0; i < mSearchables.size(); i++) { if (changingUserId == mSearchables.keyAt(i)) { getSearchables(mSearchables.keyAt(i)).buildSearchableList(); break; } } } // Inform all listeners that the list of searchables has been updated. Intent intent = new Intent(SearchManager.INTENT_ACTION_SEARCHABLES_CHANGED); intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING | Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT); mContext.sendBroadcastAsUser(intent, new UserHandle(changingUserId)); }}
在SearchManagerService的构造方法中注册,这里看到会侦听所有User的Package Changed:
new MyPackageMonitor().register(context, null, UserHandle.ALL, true);
PackageMonitor.updateSearchables()里面做两件事:(1)更新一遍Searchable info;(2)向发生了packages changed的user发SEARCHABLES_CHANGED广播。(1)里面主要的逻辑是Searchables.buildSearchableList():
/** * Builds an entire list (suitable for display) of * activities that are searchable, by iterating the entire set of * ACTION_SEARCH & ACTION_WEB_SEARCH intents. * * Also clears the hash of all activities -> searches which will * refill as the user clicks "search". * * This should only be done at startup and again if we know that the * list has changed. * * TODO: every activity that provides a ACTION_SEARCH intent should * also provide searchability meta-data. There are a bunch of checks here * that, if data is not found, silently skip to the next activity. This * won't help a developer trying to figure out why their activity isn't * showing up in the list, but an exception here is too rough. I would * like to find a better notification mechanism. * * TODO: sort the list somehow? UI choice. */public void buildSearchableList() { // These will become the new values at the end of the method HashMap<ComponentName, SearchableInfo> newSearchablesMap = new HashMap<ComponentName, SearchableInfo>(); ArrayList<SearchableInfo> newSearchablesList = new ArrayList<SearchableInfo>(); ArrayList<SearchableInfo> newSearchablesInGlobalSearchList = new ArrayList<SearchableInfo>(); // Use intent resolver to generate list of ACTION_SEARCH & ACTION_WEB_SEARCH receivers. List<ResolveInfo> searchList; final Intent intent = new Intent(Intent.ACTION_SEARCH); long ident = Binder.clearCallingIdentity(); try { searchList = queryIntentActivities(intent, PackageManager.GET_META_DATA); List<ResolveInfo> webSearchInfoList; final Intent webSearchIntent = new Intent(Intent.ACTION_WEB_SEARCH); webSearchInfoList = queryIntentActivities(webSearchIntent, PackageManager.GET_META_DATA); // analyze each one, generate a Searchables record, and record if (searchList != null || webSearchInfoList != null) { int search_count = (searchList == null ? 0 : searchList.size()); int web_search_count = (webSearchInfoList == null ? 0 : webSearchInfoList.size()); int count = search_count + web_search_count; for (int ii = 0; ii < count; ii++) { // for each component, try to find metadata ResolveInfo info = (ii < search_count) ? searchList.get(ii) : webSearchInfoList.get(ii - search_count); ActivityInfo ai = info.activityInfo; // Check first to avoid duplicate entries. if (newSearchablesMap.get(new ComponentName(ai.packageName, ai.name)) == null) { SearchableInfo searchable = SearchableInfo.getActivityMetaData(mContext, ai, mUserId); if (searchable != null) { newSearchablesList.add(searchable); newSearchablesMap.put(searchable.getSearchActivity(), searchable); if (searchable.shouldIncludeInGlobalSearch()) { newSearchablesInGlobalSearchList.add(searchable); } } } } } List<ResolveInfo> newGlobalSearchActivities = findGlobalSearchActivities(); // Find the global search activity ComponentName newGlobalSearchActivity = findGlobalSearchActivity( newGlobalSearchActivities); // Find the web search activity ComponentName newWebSearchActivity = findWebSearchActivity(newGlobalSearchActivity); // Store a consistent set of new values synchronized (this) { mSearchablesMap = newSearchablesMap; mSearchablesList = newSearchablesList; mSearchablesInGlobalSearchList = newSearchablesInGlobalSearchList; mGlobalSearchActivities = newGlobalSearchActivities; mCurrentGlobalSearchActivity = newGlobalSearchActivity; mWebSearchActivity = newWebSearchActivity; } } finally { Binder.restoreCallingIdentity(ident); }}
看到两点信息:(1)这部分逻辑不含对Search Setting的处理。(2)对于应用安装/卸载的处理是粗线条的。也就是说即使被安装/卸载的App并没有实现Search接口,也会全量刷新整个Searchable info。
0 0
- Android框架/系统服务是怎样管理第三方Search数据源的?
- 第三方框架管理cocoapods的使用
- 关于Android第三方框架的简介
- ANDROID 中常用的第三方框架
- Android开发常用的第三方框架
- android 第三方框架的使用
- Android开发常用的第三方框架
- Android中常用的第三方框架
- android第三方框架 xlistview 的使用
- android ndk 怎样调用第三方的so库文件
- android 常用第三方服务
- 用cocoapods管理第三方框架,以及遇到的问题
- 怎样使用TabPageIndicator 怎样依赖第三方框架
- Android常用第三方框架
- android 第三方引用框架
- 第三方物流管理系统的设计与实现
- Cocoa pods 管理第三方框架
- 使用pod管理第三方框架
- MyEclipse破解版+tomcat安装+jdk
- [Python 爬虫之路4] 使用selenium爬取知乎任意一个问题下,所有回答中的图片
- Android TextView 添加下划线的几种方式
- Spring Web MVC基础的一个小实例
- 详解google Chrome浏览器(理论篇)
- Android框架/系统服务是怎样管理第三方Search数据源的?
- 《趣学Python编程》笔记---第一部分:学习编程(2)
- Activiry的启动模式
- int、integer比较。。。。
- 关于面试跳槽之类的
- 牛客模拟一:连续整数
- 什么时候使用CountDownLatch
- HTTP 超文本传输协议
- Spring3中好用的工具类收集