1.ContentResolver如何應用
public void testQuery() {
Uri uri = Uri.parse("content://cn.xyCompany.providers.personProvider/person/19");
ContentResolver resolver = this.getContext().getContentResolver();
Cursor cursor = resolver.query(uri, new String[]{"id","name","phone"}, null, null, "id asc");
if(cursor.moveToFirst()) {
Log.i("query", cursor.getString(cursor.getColumnIndex("name")));
}
cursor.close();
}複製程式碼
2.ContentResolver是個啥
806 @Override
807 public ContentResolver getContentResolver() {
808 return mContentResolver;
809 }複製程式碼
2224 private ContextImpl(ContextImpl container, ActivityThread mainThread,
2225 LoadedApk packageInfo, IBinder activityToken, UserHandle user, boolean restricted,
2226 Display display, Configuration overrideConfiguration) {
2227 mOuterContext = this;
2228
2229 mMainThread = mainThread;
2230 mActivityToken = activityToken;
2231 mRestricted = restricted;
2232
2233 if (user == null) {
2234 user = Process.myUserHandle();
2235 }
2236 mUser = user;
2237
2238 mPackageInfo = packageInfo;
2239 mResourcesManager = ResourcesManager.getInstance();
2250 }
2251 mDisplayAdjustments.setCompatibilityInfo(compatInfo);
2252 mDisplayAdjustments.setActivityToken(activityToken);
2253
2254 Resources resources = packageInfo.getResources(mainThread);
2267 mResources = resources;
2286 mContentResolver = new ApplicationContentResolver(this, mainThread, user);
2287 }複製程式碼
2407 private static final class ApplicationContentResolver extends ContentResolver {
2408 private final ActivityThread mMainThread;
2409 private final UserHandle mUser;
2410
2411 public ApplicationContentResolver(
2412 Context context, ActivityThread mainThread, UserHandle user) {
2413 super(context);
2414 mMainThread = Preconditions.checkNotNull(mainThread);
2415 mUser = Preconditions.checkNotNull(user);
2416 }
2417
2418 @Override
2419 protected IContentProvider acquireProvider(Context context, String auth) {
2420 return mMainThread.acquireProvider(context,
2421 ContentProvider.getAuthorityWithoutUserId(auth),
2422 resolveUserIdFromAuthority(auth), true);
2423 }
2424
2425 @Override
2426 protected IContentProvider acquireExistingProvider(Context context, String auth) {
2427 return mMainThread.acquireExistingProvider(context,
2428 ContentProvider.getAuthorityWithoutUserId(auth),
2429 resolveUserIdFromAuthority(auth), true);
2430 }
2431
2432 @Override
2433 public boolean releaseProvider(IContentProvider provider) {
2434 return mMainThread.releaseProvider(provider, true);
2435 }
2436
2437 @Override
2438 protected IContentProvider acquireUnstableProvider(Context c, String auth) {
2439 return mMainThread.acquireProvider(c,
2440 ContentProvider.getAuthorityWithoutUserId(auth),
2441 resolveUserIdFromAuthority(auth), false);
2442 }
2443
2444 @Override
2445 public boolean releaseUnstableProvider(IContentProvider icp) {
2446 return mMainThread.releaseProvider(icp, false);
2447 }
2448
2449 @Override
2450 public void unstableProviderDied(IContentProvider icp) {
2451 mMainThread.handleUnstableProviderDied(icp.asBinder(), true);
2452 }
2453
2454 @Override
2455 public void appNotRespondingViaProvider(IContentProvider icp) {
2456 mMainThread.appNotRespondingViaProvider(icp.asBinder());
2457 }
2458
2459 /** @hide */
2460 protected int resolveUserIdFromAuthority(String auth) {
2461 return ContentProvider.getUserIdFromAuthority(auth, mUser.getIdentifier());
2462 }
2463 }
2464}複製程式碼
282 public ContentResolver(Context context) {
283 mContext = context != null ? context : ActivityThread.currentApplication();
284 mPackageName = mContext.getOpPackageName();
285 }
286
287 /** @hide */
288 protected abstract IContentProvider acquireProvider(Context c, String name);
289
290 /**
291 * Providing a default implementation of this, to avoid having to change a
292 * lot of other things, but implementations of ContentResolver should
293 * implement it.
294 *
295 * @hide
296 */
297 protected IContentProvider acquireExistingProvider(Context c, String name) {
298 return acquireProvider(c, name);
299 }
300
301 /** @hide */
302 public abstract boolean releaseProvider(IContentProvider icp);
303 /** @hide */
304 protected abstract IContentProvider acquireUnstableProvider(Context c, String name);
305 /** @hide */
306 public abstract boolean releaseUnstableProvider(IContentProvider icp);
307 /** @hide */
308 public abstract void unstableProviderDied(IContentProvider icp);複製程式碼
420 public final Cursor query(Uri uri, String[] projection,
421 String selection, String[] selectionArgs, String sortOrder) {
422 return query(uri, projection, selection, selectionArgs, sortOrder, null);
423 }複製程式碼
459 public final Cursor query(final Uri uri, String[] projection,
460 String selection, String[] selectionArgs, String sortOrder,
461 CancellationSignal cancellationSignal) {
462 IContentProvider unstableProvider = acquireUnstableProvider(uri);
463 if (unstableProvider == null) {
464 return null;
465 }
466 IContentProvider stableProvider = null;
467 Cursor qCursor = null;
468 try {
469 long startTime = SystemClock.uptimeMillis();
470
477 try {
478 qCursor = unstableProvider.query(mPackageName, uri, projection,
479 selection, selectionArgs, sortOrder, remoteCancellationSignal);
480 } catch (DeadObjectException e) {
484 unstableProviderDied(unstableProvider);
485 stableProvider = acquireProvider(uri);
486 if (stableProvider == null) {
487 return null;
488 }
489 qCursor = stableProvider.query(mPackageName, uri, projection,
490 selection, selectionArgs, sortOrder, remoteCancellationSignal);
491 }
492 if (qCursor == null) {
493 return null;
494 }
495
497 qCursor.getCount();
498 long durationMillis = SystemClock.uptimeMillis() - startTime;
500
501 // Wrap the cursor object into CursorWrapperInner object.
502 CursorWrapperInner wrapper = new CursorWrapperInner(qCursor,
503 stableProvider != null ? stableProvider : acquireProvider(uri));
504 stableProvider = null;
505 qCursor = null;
506 return wrapper;
507 } catch (RemoteException e) {
510 return null;
511 } finally {
512 if (qCursor != null) {
513 qCursor.close();
514 }
515 if (cancellationSignal != null) {
516 cancellationSignal.setRemote(null);
517 }
518 if (unstableProvider != null) {
519 releaseUnstableProvider(unstableProvider);
520 }
521 if (stableProvider != null) {
522 releaseProvider(stableProvider);
523 }
524 }
525 }複製程式碼
1360 public final Bundle call(Uri uri, String method, String arg, Bundle extras) {
1361 if (uri == null) {
1362 throw new NullPointerException("uri == null");
1363 }
1364 if (method == null) {
1365 throw new NullPointerException("method == null");
1366 }
1367 IContentProvider provider = acquireProvider(uri);
1368 if (provider == null) {
1369 throw new IllegalArgumentException("Unknown URI " + uri);
1370 }
1371 try {
1372 return provider.call(mPackageName, method, arg, extras);
1373 } catch (RemoteException e) {
1374 // Arbitrary and not worth documenting, as Activity
1375 // Manager will kill this process shortly anyway.
1376 return null;
1377 } finally {
1378 releaseProvider(provider);
1379 }
1380 }複製程式碼
1360 public final Bundle call(Uri uri, String method, String arg, Bundle extras) {
1367 IContentProvider provider = acquireProvider(uri);
1371 try {
1372 return provider.call(mPackageName, method, arg, extras);
1373 } catch (RemoteException e) {
1376 return null;
1377 } finally {
1378 releaseProvider(provider);
1379 }
1380 }複製程式碼
1.首先利用在ActivityThread中呼叫ActivityManagerNative.getDefault().getContentProvider,最終可以得到一個IContentProvider
首先從快取mProviderMap中獲取IContentProvider,如果快取命中則返回,如果沒有命中則通過ActivityManagerNative來獲取holder並保持到mProviderMap中
4574 public final IContentProvider acquireProvider(
4575 Context c, String auth, int userId, boolean stable) {
4576 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
4577 if (provider != null) {
4578 return provider;
4579 }
4580
4587 IActivityManager.ContentProviderHolder holder = null;
4588 try {
4589 holder = ActivityManagerNative.getDefault().getContentProvider(
4590 getApplicationThread(), auth, userId, stable);
4591 } catch (RemoteException ex) {
4592 }
4593 if (holder == null) {
4594 Slog.e(TAG, "Failed to find provider info for " + auth);
4595 return null;
4596 }
4600 holder = installProvider(c, holder, holder.info,
4601 true /*noisy*/, holder.noReleaseNeeded, stable);
4602 return holder.provider;
4603 }
9204 private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
9205 String name, IBinder token, boolean stable, int userId) {
9206 ContentProviderRecord cpr;
9207 ContentProviderConnection conn = null;
9208 ProviderInfo cpi = null;
9209
9210 synchronized(this) {
9247
9248 boolean providerRunning = cpr != null;
9249 if (providerRunning) {
9250 cpi = cpr.info;
9251 String msg;
9259 if (r != null && cpr.canRunHere(r)) {
9267 holder.provider = null;
9268 return holder;
9269 }
9332 boolean singleton;
9430 // This is single process, and our app is now connecting to it.
9431 // See if we are already in the process of launching this
9432 // provider.
9433 final int N = mLaunchingProviders.size();
9434 int i;
9435 for (i=0; i<N; i++) {
9436 if (mLaunchingProviders.get(i) == cpr) {
9437 break;
9438 }
9439 }
9440
9441 // If the provider is not already being launched, then get it
9442 // started.
9443 if (i >= N) {
9444 final long origId = Binder.clearCallingIdentity();
9445
9446 try {
9461 ProcessRecord proc = getProcessRecordLocked(
9462 cpi.processName, cpr.appInfo.uid, false);
9463 if (proc != null && proc.thread != null) {
9468 proc.pubProviders.put(cpi.name, cpr);
9469 try {
9470 proc.thread.scheduleInstallProvider(cpi);
9471 } catch (RemoteException e) {
9472 }
9473 } else {
9474 checkTime(startTime, "getContentProviderImpl: before start process");
9475 proc = startProcessLocked(cpi.processName,
9476 cpr.appInfo, false, 0, "content provider",
9477 new ComponentName(cpi.applicationInfo.packageName,
9478 cpi.name), false, false, false);
9480 if (proc == null) {
9485 return null;
9486 }
9487 }
9488 cpr.launchingApp = proc;
9489 mLaunchingProviders.add(cpr);
9490 } finally {
9491 Binder.restoreCallingIdentity(origId);
9492 }
9493 }
9508 }
9510 }
9511
9513 synchronized (cpr) {
9514 while (cpr.provider == null) {
9515 if (cpr.launchingApp == null) {
9524 return null;
9525 }
9526 try {
9531 if (conn != null) {
9532 conn.waiting = true;
9533 }
9534 cpr.wait();
9535 } catch (InterruptedException ex) {
9536 } finally {
9537 if (conn != null) {
9538 conn.waiting = false;
9539 }
9540 }
9541 }
9542 }
9543 return cpr != null ? cpr.newHolder(conn) : null;
9544 }
2515 public void handleInstallProvider(ProviderInfo info) {
2516 installContentProviders(mInitialApplication, Lists.newArrayList(info));
2517 }複製程式碼
2.如果程式沒有啟動則啟動程式,否則進入3
3.呼叫thread.scheuleInstallProvider
這裡很奇怪,為什麼會有步驟三呢?應用程式啟動的時候在handleBindApplication中,不是已經安裝了所有的Provider元件嗎?莫非是中途被幹掉了,比如禁用了元件!
4545 private void installContentProviders(
4546 Context context, List<ProviderInfo> providers) {
4547 final ArrayList<IActivityManager.ContentProviderHolder> results =
4548 new ArrayList<IActivityManager.ContentProviderHolder>();
4549
4550 for (ProviderInfo cpi : providers) {
4551 if (DEBUG_PROVIDER) {
4552 StringBuilder buf = new StringBuilder(128);
4553 buf.append("Pub ");
4554 buf.append(cpi.authority);
4555 buf.append(": ");
4556 buf.append(cpi.name);
4557 Log.i(TAG, buf.toString());
4558 }
4559 IActivityManager.ContentProviderHolder cph = installProvider(context, null, cpi,
4560 false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
4561 if (cph != null) {
4562 cph.noReleaseNeeded = true;
4563 results.add(cph);
4564 }
4565 }
4566
4567 try {
4568 ActivityManagerNative.getDefault().publishContentProviders(
4569 getApplicationThread(), results);
4570 } catch (RemoteException ex) {
4571 }
4572 }複製程式碼
4918 private IActivityManager.ContentProviderHolder installProvider(Context context,
4919 IActivityManager.ContentProviderHolder holder, ProviderInfo info,
4920 boolean noisy, boolean noReleaseNeeded, boolean stable) {
4921 ContentProvider localProvider = null;
4922 IContentProvider provider;
4923 if (holder == null || holder.provider == null) {
4924 if (DEBUG_PROVIDER || noisy) {
4925 Slog.d(TAG, "Loading provider " + info.authority + ": "
4926 + info.name);
4927 }
4928 Context c = null;
4929 ApplicationInfo ai = info.applicationInfo;
4950 try {
4951 final java.lang.ClassLoader cl = c.getClassLoader();
4952 localProvider = (ContentProvider)cl.
4953 loadClass(info.name).newInstance();
4954 provider = localProvider.getIContentProvider();
4955 if (provider == null) {
4959 return null;
4960 }
4964 localProvider.attachInfo(c, info);
4965 } catch (java.lang.Exception e) {
4971 return null;
4972 }
4973 } else {
4974 provider = holder.provider;
4977 }
4978
4979 IActivityManager.ContentProviderHolder retHolder;
4980
4981 synchronized (mProviderMap) {
4984 IBinder jBinder = provider.asBinder();
4985 if (localProvider != null) {
4986 ComponentName cname = new ComponentName(info.packageName, info.name);
4987 ProviderClientRecord pr = mLocalProvidersByName.get(cname);
4988 if (pr != null) {
4993 provider = pr.mProvider;
4994 } else {
4995 holder = new IActivityManager.ContentProviderHolder(info);
4996 holder.provider = provider;
4997 holder.noReleaseNeeded = true;
4998 pr = installProviderAuthoritiesLocked(provider, localProvider, holder);
4999 mLocalProviders.put(jBinder, pr);
5000 mLocalProvidersByName.put(cname, pr);
5001 }
5002 retHolder = pr.mHolder;
5003 } else {
5004 ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
5005 if (prc != null) {
5013 if (!noReleaseNeeded) {
5014 incProviderRefLocked(prc, stable);
5015 try {
5016 ActivityManagerNative.getDefault().removeContentProvider(
5017 holder.connection, stable);
5018 } catch (RemoteException e) {
5020 }
5021 }
5022 } else {
5023 ProviderClientRecord client = installProviderAuthoritiesLocked(
5024 provider, localProvider, holder);
5025 if (noReleaseNeeded) {
5026 prc = new ProviderRefCount(holder, client, 1000, 1000);
5027 } else {
5028 prc = stable
5029 ? new ProviderRefCount(holder, client, 1, 0)
5030 : new ProviderRefCount(holder, client, 0, 1);
5031 }
5032 mProviderRefCountMap.put(jBinder, prc);
5033 }
5034 retHolder = prc.holder;
5035 }
5036 }
5037
5038 return retHolder;
5039 }複製程式碼
4884 private ProviderClientRecord installProviderAuthoritiesLocked(IContentProvider provider,
4885 ContentProvider localProvider, IActivityManager.ContentProviderHolder holder) {
4886 final String auths[] = PATTERN_SEMICOLON.split(holder.info.authority);
4887 final int userId = UserHandle.getUserId(holder.info.applicationInfo.uid);
4888
4889 final ProviderClientRecord pcr = new ProviderClientRecord(
4890 auths, provider, localProvider, holder);
4891 for (String auth : auths) {
4892 final ProviderKey key = new ProviderKey(auth, userId);
4893 final ProviderClientRecord existing = mProviderMap.get(key);
4894 if (existing != null) {
4897 } else {
4898 mProviderMap.put(key, pcr);
4899 }
4900 }
4901 return pcr;
4902 }複製程式碼
4254 private void handleBindApplication(AppBindData data) {
4255 mBoundApplication = data;
4328
4329 final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
4343
4483
4487 final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskWrites();
4488 try {
4491 Application app = data.info.makeApplication(data.restrictedBackupMode, null);
4492 mInitialApplication = app;
4493
4496 if (!data.restrictedBackupMode) {
4497 List<ProviderInfo> providers = data.providers;
4498 if (providers != null) {
4499 installContentProviders(app, providers);
4502 mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
4503 }
4504 }
4505
4506 // Do this after providers, since instrumentation tests generally start their
4507 // test thread at this point, and we don't want that racing.
4508 try {
4509 mInstrumentation.onCreate(data.instrumentationArgs);
4510 }
4511 catch (Exception e) {
4515 }
4516
4517 try {
4518 mInstrumentation.callApplicationOnCreate(app);
4519 } catch (Exception e) {
4525 }
4526 } finally {
4527 StrictMode.setThreadPolicy(savedPolicy);
4528 }
4529 }
複製程式碼
9643 public final void publishContentProviders(IApplicationThread caller,
9644 List<ContentProviderHolder> providers) {
9650 synchronized (this) {
9651 final ProcessRecord r = getRecordForAppLocked(caller);
9660
9661 final long origId = Binder.clearCallingIdentity();
9662
9663 final int N = providers.size();
9664 for (int i=0; i<N; i++) {
9665 ContentProviderHolder src = providers.get(i);
9666 if (src == null || src.info == null || src.provider == null) {
9667 continue;
9668 }
9669 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
9672 if (dst != null) {
9673 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
9674 mProviderMap.putProviderByClass(comp, dst);
9675 String names[] = dst.info.authority.split(";");
9676 for (int j = 0; j < names.length; j++) {
9677 mProviderMap.putProviderByName(names[j], dst);
9678 }
9679
9680 int NL = mLaunchingProviders.size();
9681 int j;
9682 for (j=0; j<NL; j++) {
9683 if (mLaunchingProviders.get(j) == dst) {
9684 mLaunchingProviders.remove(j);
9685 j--;
9686 NL--;
9687 }
9688 }
9689 synchronized (dst) {
9690 dst.provider = src.provider;
9691 dst.proc = r;
9692 dst.notifyAll();
9693 }
9694 updateOomAdjLocked(r);
9695 }
9696 }
9697
9698 Binder.restoreCallingIdentity(origId);
9699 }
9700 }複製程式碼
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
為什麼ContentProviderNative傳遞到另外一個程式中,最後變成了ContentProviderProxy呢?這其實很簡單,首先遵循基本的Binder機制,ContentProviderNative在natvie層表述為BBinder,透過Binder驅動傳遞到另外一個程式後,會變成BpBinder,如果是Java層接收在Parcel中會將其轉化為BindProxy的Java物件。最後上層使用了ContentProviderHolder序列化資料,在接收到BindProxy後會呼叫ContentProviderNative.asInterface(IBinder)靜態函式,看看程式碼就會明白了了,new ContentProviderProxy(new BindProxy(BpBinder(handle))). 這行程式碼挺帶感的,順便再寫一句吧new ContentProviderNative().mObject=new JavaBBinderHolder().mObject=new JavaBBinder(ContentProviderNative)。