Contentprovider 注册 启动简单流程
安装app时packagemanager 读取manixfest获取provider信息 存在数据库里
流程:
1、加载ActivityThread main方法,创建消息队列。ActivityThread.main:
Looper.prepareMainLooper();
ActivityThread thread = new ActivityThread();
thread.attach(false); (2)
sMainThreadHandler = thread.getHandler();
Looper.loop();
2、ActivityThread.attach:
final IActivityManager mgr = ActivityManagerNative.getDefault();
mgr.attachApplication(mAppThread); //IPC把ApplicationThread 传递给AMS (3)
mInstrumentation = new Instrumentation();
ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);
mInitialApplication = context.mPackageInfo.makeApplication(true, null);
3、ActivityManagerService.attachApplication => ActivityManagerService.attachApplicationLocked:
List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) //获取packageManager中这个包注册的provider信息
thread.bindApplication(processName, appInfo, providers, ...) //IPC调用app端的bindApplication
4. ActivityThread.bindApplication => ActivityThread.handleBindApplication
List<ProviderInfo> providers = data.providers;
installContentProviders(app, providers); (5)
mInstrumentation.callApplicationOnCreate(app); // call Application.onCreate()
5. ActivityThread.installContentProviders:
IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi, false, true, true); //实例化provider类
results.add(cph);
ActivityManagerNative.getDefault().publishContentProviders(getApplicationThread(), results); //发布到AMS
6. ActivityManagerService.publishContentProviders: //把ContentProviderRecord存储起来,放到mProviderMap中去
ContentProviderRecord dst = r.pubProviders.get(src.info.name);
ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
mProviderMap.putProviderByClass(comp, dst);
调用contentprovider:
当调用ContentProvider的insert、delete、update、query方法中的任何一个时,如果ContentProvider所在的进程没有启动的话,
那么就会触发ContentProvider的创建,并伴随着ContentProvider所在进程的启动。
1. ApplicationContentResolver.acquireProvider:
holder = ActivityManagerNative.getDefault().getContentProvider(
getApplicationThread(), auth, userId, stable); //从AMS获取contentprovider的binder
2. ActivityManagerService.getContentProviderImpl
//先从mProviderMap中找已经publish的provider 返回这个provider
ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
//如果cpr不存在
ProviderInfo cpi = AppGlobals.getPackageManager().resolveContentProvider(name, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, UserHandle.USER_OWNER);
cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
//获取provider所在进程
ProcessRecord proc = getProcessRecordLocked(cpi.processName, cpr.appInfo.uid, false);
if (proc != null && proc.thread != null) {
//如果已启动
proc.thread.scheduleInstallProvider(cpi);
} else {
proc = startProcessLocked(cpi.processName,
cpr.appInfo, false, 0, "content provider",
new ComponentName(cpi.applicationInfo.packageName,
cpi.name), false, false, false);
}
//等待直到provider publish成功
最新文章
- easyui combobox 带 checkbox
- 【226】C# 相关功能实现代码
- 三栏布局的n种实现
- shell 验证ip
- RSA实例破解
- 转:ASP.Net MVC:校验、AJAX与过滤器
- 转 delphi SelText,GetText,SetText用法
- oracle表的简单操作
- QT之UDP通信
- Leetcode刷题C#版之 Length of Last Word
- Django基础(二):环境配置
- SDL2源代码分析2:窗口(SDL_Window)
- Python——类的封装
- python 练习 simple_server 判断路径及返回函数
- poi包冲突问题(excel)
- vi命令插入
- Docekr 挂在卷之后访问目录时异常 cannot open directory &#39;.&#39;: Permission denied 的解决办法
- windows 活动目录双向信任配置
- Linux笔记(二): WIN 10 Ubuntu 双系统
- python 爬虫数据准换时间格式
热门文章
- C/C++操作SQLite
- 【心无旁骛】vuex-simple
- Odoo的权限
- hdu1693 Eat the Trees [插头DP经典例题]
- [编织消息框架][netty源码分析]3 EventLoop 实现类SingleThreadEventLoop职责与实现
- 刷屏的海底捞超级APP究竟是怎样与阿里云合作的
- watch、tail联合使用
- Vue简单评星效果与单张图片上传
- 二叉查找树、平衡二叉树(AVL)、B+树、联合索引
- hibernate一对多关系 在一方查询会获得重复数据,重复数量就是多端数据数量用@Fetch(FetchMode.SUBSELECT)解决