ContentProvider启动过程
启动过程: ActivityThread main -> AMS 远程调用ApplicationThread -> 通过ActivityThread的H handler切换到主线程转载ContentProvider
- 入口是ActivityThread的main,ActivityThread是管理应用所在进程的主线程的,也就是UI线程的管理者
- attach方法远程调用AMS的attachApplication,把ApplicationThread对象提供给AMS
- AMS的attachApplication会远程调用ApplicationThread的bindApplication
- handleBindApplication会创建Application对象(只创建一次),并加载ContentProvider***,然后调用Application的OnCreate方法
- ActivityThread的MProviderMap存储ContentProvider对象
- ContentProvider的android:mutiprocess属性决定它是否单实例,默认值是false,也就是默认是单实例。当设置为true时,每个调用者的进程中都存在一个ContentProvider对象。
- 当调用增删改查方法时,如果ContentProvider所在的进程如果没有启动的话会触发ContentProvider的创建,并伴随着ContentProvider所在进程的启动
代码片 ActivityThread main
6505 public static void main(String[] args) {
6506 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");
6507 SamplingProfilerIntegration.start();
6508
6509 // CloseGuard defaults to true and can be quite spammy. We
6510 // disable it here, but selectively enable it later (via
6511 // StrictMode) on debug builds, but using DropBox, not logs.
6512 CloseGuard.setEnabled(false);
6513
6514 Environment.initForCurrentUser();
6515
6516 // Set the reporter for event logging in libcore
6517 EventLogger.setReporter(new EventLoggingReporter());
6518
6519 // Make sure TrustedCertificateStore looks in the right place for CA certificates
6520 final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
6521 TrustedCertificateStore.setDefaultUserDirectory(configDir);
6522
6523 Process.setArgV0("<pre-initialized>");
6524
6525 Looper.prepareMainLooper();
6526
6527 ActivityThread thread = new ActivityThread();
6528 thread.attach(false);
6529
6530 if (sMainThreadHandler == null) {
6531 sMainThreadHandler = thread.getHandler();
6532 }
6533
6534 if (false) {
6535 Looper.myLooper().setMessageLogging(new
6536 LogPrinter(Log.DEBUG, "ActivityThread"));
6537 }
6538
6539 // End of event ActivityThreadMain.
6540 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6541 Looper.loop();
6542
6543 throw new RuntimeException("Main thread loop unexpectedly exited");
6544 }
query操作过程
ContentProvider的四个方法都是通过Binder来调用,外界无法直接访问ContentProvider
调用四个方法都要先获取IContentProvider对象,然后调用它的方法。获取时,如果进程已经在,目标ContentProvider已经存在就返回,如果不存在就进入创建过程
代码片段 一
5867 public final IContentProvider acquireProvider(
5868 Context c, String auth, int userId, boolean stable) {
// 如果已经存在,直接返回
5869 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
5870 if (provider != null) {
5871 return provider;
5872 }
5873
5874 // There is a possible race here. Another thread may try to acquire
5875 // the same provider at the same time. When this happens, we want to ensure
5876 // that the first one wins.
5877 // Note that we cannot hold the lock while acquiring and installing the
5878 // provider since it might take a long time to run and it could also potentially
5879 // be re-entrant in the case where the provider is in the same process.
// AMS启动目标Provider
5880 ContentProviderHolder holder = null;
5881 try {
5882 holder = ActivityManager.getService().getContentProvider(
5883 getApplicationThread(), auth, userId, stable);
5884 } catch (RemoteException ex) {
5885 throw ex.rethrowFromSystemServer();
5886 }
5887 if (holder == null) {
5888 Slog.e(TAG, "Failed to find provider info for " + auth);
5889 return null;
5890 }
5891
5892 // Install provider will increment the reference count for us, and break
// rum meiyo
5893 // any ties in the race.
5894 holder = installProvider(c, holder, holder.info,
5895 true /*noisy*/, holder.noReleaseNeeded, stable);
5896 return holder.provider;
5897 }
代码片段二
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
11276 String name, IBinder token, boolean stable, int userId) {
11277 ......
11563 proc = startProcessLocked(cpi.processName,
......
11601 }