�����ڵ�λ�ã���ҳ > ���� > Android���� > ����
AndroidӦ�ó������Content Provider����������Դ�������
http://www.drovik.com/      2013-1-25 22:15:36      ��Դ�����޵�Android֮��      �����
 ͨ��ǰ���ѧϰ������֪����Androidϵͳ�У�Content Provider����Ϊ��ͬ��Ӧ�ó��������ͬ�������ṩͳһ����ڡ�Content Providerһ���������ڶ����Ľ����еģ�ÿһ��Content Provider��ϵͳ��ֻ��һ��ʵ�����ڣ�����Ӧ�ó�������Ҫ�ҵ����ʵ����Ȼ����ܷ����������ݡ���ô��ϵͳ�е�Content Providerʵ������˭�������������أ����Ľ��ش�������⡣

Content Provider��Ӧ�ó������Activity��Serviceһ������Ҫ��AndroidManifest.xml�ļ�������֮�����ʹ�á�ϵͳ�ڰ�װ����Content Provider��Ӧ�ó����ʱ�򣬻����ЩContent Provider��������Ϣ������������������Ҫ�ľ���Content Provider��Authority��Ϣ��AndroidӦ�ó���İ�װ���̾�����Բο�AndroidӦ�ó���װ����Դ�������һ�ġ�ע�⣬��װӦ�ó����ʱ�򣬲��������Ӧ��Content Provider���ص��ڴ�������ϵͳ��ȡ���������صĻ��ƣ��ȵ���һ��Ҫʹ�����Content Provider��ʱ��ϵͳ�Ż�������ص��ڴ��������´���Ҫʹ�����Content Provider��ʱ�򣬾Ϳ���ֱ�ӷ����ˡ�

������ǰ��һƪ����AndroidӦ�ó������Content ProviderӦ��ʵ���е���������ϸ����Content Provider���������̡���AndroidӦ�ó������Content ProviderӦ��ʵ����ƪ���½��ܵ�Ӧ�ó���Article�У���һ��ʹ��ArticlesProvider���Content Provider�ĵط���ArticlesAdapter���getArticleCount��������ΪMainActivityҪ��ListView����ʾ������Ϣ�б�ʱ�� ����Ҫ֪��ArticlesProvider�е�������Ϣ����������ArticlesAdapter���getArticleCount�������ÿ�ʼ��һֱ��ArticlesProvider���onCreate���������ã�����ArticlesProvider�������������̣��������Ǿ��ȿ���������̵�����ͼ��Ȼ������ϸ����ÿһ�����裺

Step 1. ArticlesAdapter.getArticleCount

�������������ǰ��һƪ����AndroidӦ�ó������Content ProviderӦ��ʵ�����ܵ�Ӧ�ó���ArtilceԴ���빤��Ŀ¼�£����ļ�Ϊpackages/experimental/Article/src/shy/luo/article/ArticlesAdapter.java�У�

  1. public class ArticlesAdapter {
  2. ......
  3. private ContentResolver resolver = null;
  4. public ArticlesAdapter(Context context) {
  5. resolver = context.getContentResolver();
  6. }
  7. ......
  8. public int getArticleCount() {
  9. int count = 0;
  10. try {
  11. IContentProvider provider = resolver.acquireProvider(Articles.CONTENT_URI);
  12. Bundle bundle = provider.call(Articles.METHOD_GET_ITEM_COUNT, null, null);
  13. count = bundle.getInt(Articles.KEY_ITEM_COUNT, 0);
  14. } catch(RemoteException e) {
  15. e.printStackTrace();
  16. }
  17. return count;
  18. }
  19. ......
  20. }
public class ArticlesAdapter { ...... private ContentResolver resolver = null; public ArticlesAdapter(Context context) { resolver = context.getContentResolver(); } ...... public int getArticleCount() { int count = 0; try { IContentProvider provider = resolver.acquireProvider(Articles.CONTENT_URI); Bundle bundle = provider.call(Articles.METHOD_GET_ITEM_COUNT, null, null); count = bundle.getInt(Articles.KEY_ITEM_COUNT, 0); } catch(RemoteException e) { e.printStackTrace(); } return count; } ...... }

�������ͨ��Ӧ�ó��������ĵ�ContentResolver�ӿ�resolver��acquireProvider�����������Articles.CONTENT_URI��Ӧ��Content Provider�����IContentProvider�ӿڡ�����Articles.CONTENT_URI����Ӧ�ó���ArticlesProvider�ж���ģ�����ֵΪ��content://shy.luo.providers.articles/item������Ӧ��Content Provider����ArticlesProvider�ˡ�

Step 2. ContentResolver.acqireProvider

�������������frameworks/base/core/java/android/content/ContentResolver.java�ļ��У�

  1. public abstract class ContentResolver {
  2. ......
  3. public final IContentProvider acquireProvider(Uri uri) {
  4. if (!SCHEME_CONTENT.equals(uri.getScheme())) {
  5. return null;
  6. }
  7. String auth = uri.getAuthority();
  8. if (auth != null) {
  9. return acquireProvider(mContext, uri.getAuthority());
  10. }
  11. return null;
  12. }
  13. ......
  14. }
public abstract class ContentResolver { ...... public final IContentProvider acquireProvider(Uri uri) { if (!SCHEME_CONTENT.equals(uri.getScheme())) { return null; } String auth = uri.getAuthority(); if (auth != null) { return acquireProvider(mContext, uri.getAuthority()); } return null; } ...... }

����������֤����uri��scheme�Ƿ���ȷ�����Ƿ�����content://��ͷ��Ȼ��ȡ������authority���֣�����������һ����Ա����acquireProviderִ�л�ȡContentProvider�ӿڵIJ���������������龰�У�����uri��authority�����ݱ��ǡ�shy.luo.providers.articles���ˡ�

��ContentResolver��Ķ������ǿ��Կ���������һ�������࣬���������汾��acquireProvider������������������ʵ�ֵġ��ص�Step 1�У����ContentResolver�ӿ���ͨ��Ӧ�ó���������Context�����getContentResolver��������õģ���Ӧ�ó���������Context����ContextImpl����ʵ�ֵģ���������frameworks/base/core/java/android/app/ContextImpl.java�ļ��У�

  1. class ContextImpl extends Context {
  2. ......
  3. private ApplicationContentResolver mContentResolver;
  4. ......
  5. final void init(LoadedApk packageInfo,
  6. IBinder activityToken, ActivityThread mainThread,
  7. Resources container) {
  8. ......
  9. mContentResolver = new ApplicationContentResolver(this, mainThread);
  10. ......
  11. }
  12. ......
  13. @Override
  14. public ContentResolver getContentResolver() {
  15. return mContentResolver;
  16. }
  17. ......
  18. }
class ContextImpl extends Context { ...... private ApplicationContentResolver mContentResolver; ...... final void init(LoadedApk packageInfo, IBinder activityToken, ActivityThread mainThread, Resources container) { ...... mContentResolver = new ApplicationContentResolver(this, mainThread); ...... } ...... @Override public ContentResolver getContentResolver() { return mContentResolver; } ...... }

ContextImpl���init��������Ӧ�ó���������ʱ����õģ�������Բο�AndroidӦ�ó�����������Դ�������һ���е�Step 34��

��ˣ��������ContentResolver���acquireProvider�������������Ҫ���õ�ApplicationContentResolver���acquireProvider������

Step 3. ApplicationContentResolve.acquireProvider

�������������frameworks/base/core/java/android/app/ContextImpl.java�ļ��У�

  1. class ContextImpl extends Context {
  2. ......
  3. private static final class ApplicationContentResolver extends ContentResolver {
  4. ......
  5. @Override
  6. protected IContentProvider acquireProvider(Context context, String name) {
  7. return mMainThread.acquireProvider(context, name);
  8. }
  9. ......
  10. private final ActivityThread mMainThread;
  11. }
  12. ......
  13. }
class ContextImpl extends Context { ...... private static final class ApplicationContentResolver extends ContentResolver { ...... @Override protected IContentProvider acquireProvider(Context context, String name) { return mMainThread.acquireProvider(context, name); } ...... private final ActivityThread mMainThread; } ...... }

������ActivityThread���acquireProvider������һ��ִ�л�ȡContent Provider�ӿڵIJ�����

Step 4. ActivityThread.acquireProvider

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. public final IContentProvider acquireProvider(Context c, String name) {
  4. IContentProvider provider = getProvider(c, name);
  5. if(provider == null)
  6. return null;
  7. ......
  8. return provider;
  9. }
  10. ......
  11. }
public final class ActivityThread { ...... public final IContentProvider acquireProvider(Context c, String name) { IContentProvider provider = getProvider(c, name); if(provider == null) return null; ...... return provider; } ...... }

�����ǵ���������һ����Ա����getProvider����һ��ִ�л�ȡContent Provider�ӿڵIJ�����

Step 5. ActivityThread.getProvider

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. private final IContentProvider getExistingProvider(Context context, String name) {
  4. synchronized(mProviderMap) {
  5. final ProviderClientRecord pr = mProviderMap.get(name);
  6. if (pr != null) {
  7. return pr.mProvider;
  8. }
  9. return null;
  10. }
  11. }
  12. ......
  13. private final IContentProvider getProvider(Context context, String name) {
  14. IContentProvider existing = getExistingProvider(context, name);
  15. if (existing != null) {
  16. return existing;
  17. }
  18. IActivityManager.ContentProviderHolder holder = null;
  19. try {
  20. holder = ActivityManagerNative.getDefault().getContentProvider(
  21. getApplicationThread(), name);
  22. } catch (RemoteException ex) {
  23. }
  24. IContentProvider prov = installProvider(context, holder.provider,
  25. holder.info, true);
  26. ......
  27. return prov;
  28. }
  29. ......
  30. }
public final class ActivityThread { ...... private final IContentProvider getExistingProvider(Context context, String name) { synchronized(mProviderMap) { final ProviderClientRecord pr = mProviderMap.get(name); if (pr != null) { return pr.mProvider; } return null; } } ...... private final IContentProvider getProvider(Context context, String name) { IContentProvider existing = getExistingProvider(context, name); if (existing != null) { return existing; } IActivityManager.ContentProviderHolder holder = null; try { holder = ActivityManagerNative.getDefault().getContentProvider( getApplicationThread(), name); } catch (RemoteException ex) { } IContentProvider prov = installProvider(context, holder.provider, holder.info, true); ...... return prov; } ...... }

����������Ȼ�ͨ��getExistingProvider��������鱾���Ƿ��Ѿ��������Ҫ��ȡ��ContentProvider�ӿڣ�������ڣ���ֱ�ӷ����ˡ������Ѿ����ڵ�ContextProvider�ӿڱ�����ActivityThread���mProviderMap��Ա�����У���ContentProvider��Ӧ��URI��authorityΪ��ֵ���档����������龰�У���Ϊ�ǵ�һ�ε���ArticlesProvider�ӿڣ���ˣ���ʱ��ͨ��getExistingProvider�����õ���IContentProvider�ӿ�Ϊnull����������ͻ����ActivityManagerService�����getContentProvider�ӿ�����ȡһ��ContentProviderHolder����holder���������Ͱ�����������Ҫ��ȡ��ArticlesProvider�ӿڣ��ڽ�����ӿڷ��ظ�������֮�󣬻������installProvider������������ӿڱ����ڱ����У��Ա��´�Ҫʹ�����ContentProvider�ӿ�ʱ��ֱ�ӾͿ���ͨ��getExistingProvider������ȡ�ˡ�

�����Ƚ��뵽ActivityManagerService�����getContentProvider�����п���������λ�ȡ��������Ҫ��ArticlesProvider�ӿڵģ�Ȼ���ٷ���������installProvider������ʵ�֡�

Step 6. ActivityManagerService.getContentProvider

�������������frameworks/base/services/java/com/android/server/am/ActivityManagerService.java�ļ��У�

  1. public final class ActivityManagerService extends ActivityManagerNative
  2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  3. ......
  4. public final ContentProviderHolder getContentProvider(
  5. IApplicationThread caller, String name) {
  6. ......
  7. return getContentProviderImpl(caller, name);
  8. }
  9. ......
  10. }
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public final ContentProviderHolder getContentProvider( IApplicationThread caller, String name) { ...... return getContentProviderImpl(caller, name); } ...... }

������getContentProviderImpl��������һ��ִ�в�����

Step 7. ActivityManagerService.getContentProviderImpl

�������������frameworks/base/services/java/com/android/server/am/ActivityManagerService.java�ļ��У�

  1. public final class ActivityManagerService extends ActivityManagerNative
  2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  3. ......
  4. private final ContentProviderHolder getContentProviderImpl(
  5. IApplicationThread caller, String name) {
  6. ContentProviderRecord cpr;
  7. ProviderInfo cpi = null;
  8. synchronized(this) {
  9. ProcessRecord r = null;
  10. if (caller != null) {
  11. r = getRecordForAppLocked(caller);
  12. ......
  13. }
  14. // First check if this content provider has been published...
  15. cpr = mProvidersByName.get(name);
  16. if (cpr != null) {
  17. ......
  18. } else {
  19. try {
  20. cpi = AppGlobals.getPackageManager().
  21. resolveContentProvider(name,
  22. STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
  23. } catch (RemoteException ex) {
  24. }
  25. ......
  26. }
  27. cpr = mProvidersByClass.get(cpi.name);
  28. final boolean firstClass = cpr == null;
  29. if (firstClass) {
  30. try {
  31. ApplicationInfo ai =
  32. AppGlobals.getPackageManager().
  33. getApplicationInfo(
  34. cpi.applicationInfo.packageName,
  35. STOCK_PM_FLAGS);
  36. ......
  37. cpr = new ContentProviderRecord(cpi, ai);
  38. } catch (RemoteException ex) {
  39. // pm is in same process, this will never happen.
  40. }
  41. }
  42. if (r != null && cpr.canRunHere(r)) {
  43. // If this is a multiprocess provider, then just return its
  44. // info and allow the caller to instantiate it. Only do
  45. // this if the provider is the same user as the caller's
  46. // process, or can run as root (so can be in any process).
  47. return cpr;
  48. }
  49. ......
  50. // This is single process, and our app is now connecting to it.
  51. // See if we are already in the process of launching this
  52. // provider.
  53. final int N = mLaunchingProviders.size();
  54. int i;
  55. for (i=0; i<N; i++) {
  56. if (mLaunchingProviders.get(i) == cpr) {
  57. break;
  58. }
  59. }
  60. // If the provider is not already being launched, then get it
  61. // started.
  62. if (i >= N) {
  63. final long origId = Binder.clearCallingIdentity();
  64. ProcessRecord proc = startProcessLocked(cpi.processName,
  65. cpr.appInfo, false, 0, "content provider",
  66. new ComponentName(cpi.applicationInfo.packageName,
  67. cpi.name), false);
  68. ......
  69. mLaunchingProviders.add(cpr);
  70. ......
  71. }
  72. // Make sure the provider is published (the same provider class
  73. // may be published under multiple names).
  74. if (firstClass) {
  75. mProvidersByClass.put(cpi.name, cpr);
  76. }
  77. cpr.launchingApp = proc;
  78. mProvidersByName.put(name, cpr);
  79. ......
  80. }
  81. // Wait for the provider to be published...
  82. synchronized (cpr) {
  83. while (cpr.provider == null) {
  84. ......
  85. try {
  86. cpr.wait();
  87. } catch (InterruptedException ex) {
  88. }
  89. }
  90. }
  91. return cpr;
  92. }
  93. ......
  94. }
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final ContentProviderHolder getContentProviderImpl( IApplicationThread caller, String name) { ContentProviderRecord cpr; ProviderInfo cpi = null; synchronized(this) { ProcessRecord r = null; if (caller != null) { r = getRecordForAppLocked(caller); ...... } // First check if this content provider has been published... cpr = mProvidersByName.get(name); if (cpr != null) { ...... } else { try { cpi = AppGlobals.getPackageManager(). resolveContentProvider(name, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); } catch (RemoteException ex) { } ...... } cpr = mProvidersByClass.get(cpi.name); final boolean firstClass = cpr == null; if (firstClass) { try { ApplicationInfo ai = AppGlobals.getPackageManager(). getApplicationInfo( cpi.applicationInfo.packageName, STOCK_PM_FLAGS); ...... cpr = new ContentProviderRecord(cpi, ai); } catch (RemoteException ex) { // pm is in same process, this will never happen. } } if (r != null && cpr.canRunHere(r)) { // If this is a multiprocess provider, then just return its // info and allow the caller to instantiate it. Only do // this if the provider is the same user as the caller's // process, or can run as root (so can be in any process). return cpr; } ...... // This is single process, and our app is now connecting to it. // See if we are already in the process of launching this // provider. final int N = mLaunchingProviders.size(); int i; for (i=0; i<N; i++) { if (mLaunchingProviders.get(i) == cpr) { break; } } // If the provider is not already being launched, then get it // started. if (i >= N) { final long origId = Binder.clearCallingIdentity(); ProcessRecord proc = startProcessLocked(cpi.processName, cpr.appInfo, false, 0, "content provider", new ComponentName(cpi.applicationInfo.packageName, cpi.name), false); ...... mLaunchingProviders.add(cpr); ...... } // Make sure the provider is published (the same provider class // may be published under multiple names). if (firstClass) { mProvidersByClass.put(cpi.name, cpr); } cpr.launchingApp = proc; mProvidersByName.put(name, cpr); ...... } // Wait for the provider to be published... synchronized (cpr) { while (cpr.provider == null) { ...... try { cpr.wait(); } catch (InterruptedException ex) { } } } return cpr; } ...... }

��������Ƚϳ�������һ��һ���ط�����
���������ǻ�ȡ�����ߵĽ��̼�¼����Ϣ��

  1. ProcessRecord r = null;
  2. if (caller != null) {
  3. r = getRecordForAppLocked(caller);
  4. ......
  5. }
ProcessRecord r = null; if (caller != null) { r = getRecordForAppLocked(caller); ...... }

����������龰�У�Ҫ��ȡ�ľ���Ӧ�ó���Article�Ľ��̼�¼����Ϣ�ˣ�������õ���

��ActivityManagerService�У���������Ա��������������ϵͳ�е�Content Provider��Ϣ�ģ�һ����mProvidersByName��һ����mProvidersByClass��ǰ������Content Provider��authoriryֵΪ��ֵ������ģ���������Content Provider������Ϊ��ֵ������ġ�һ��Content Provider�����ж��authority����ֻ��һ������������Ӧ����ˣ�����Ҫ������Map�����棬����Ϊ�˷�����ݲ�ͬ���������ٲ��Ҷ���Ƶġ�����Ĵ�������������Ҫ��ȡ��Content Provider�Ƿ��Ѿ��Ӵ��ڵ��ˣ�

  1. // First check if this content provider has been published...
  2. cpr = mProvidersByName.get(name);
  3. if (cpr != null) {
  4. ......
  5. } else {
  6. try {
  7. cpi = AppGlobals.getPackageManager().
  8. resolveContentProvider(name,
  9. STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
  10. } catch (RemoteException ex) {
  11. }
  12. ......
  13. }
  14. cpr = mProvidersByClass.get(cpi.name);
  15. final boolean firstClass = cpr == null;
  16. if (firstClass) {
  17. try {
  18. ApplicationInfo ai =
  19. AppGlobals.getPackageManager().
  20. getApplicationInfo(
  21. cpi.applicationInfo.packageName,
  22. STOCK_PM_FLAGS);
  23. ......
  24. cpr = new ContentProviderRecord(cpi, ai);
  25. } catch (RemoteException ex) {
  26. // pm is in same process, this will never happen.
  27. }
  28. }
// First check if this content provider has been published... cpr = mProvidersByName.get(name); if (cpr != null) { ...... } else { try { cpi = AppGlobals.getPackageManager(). resolveContentProvider(name, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); } catch (RemoteException ex) { } ...... } cpr = mProvidersByClass.get(cpi.name); final boolean firstClass = cpr == null; if (firstClass) { try { ApplicationInfo ai = AppGlobals.getPackageManager(). getApplicationInfo( cpi.applicationInfo.packageName, STOCK_PM_FLAGS); ...... cpr = new ContentProviderRecord(cpi, ai); } catch (RemoteException ex) { // pm is in same process, this will never happen. } }

����������龰�У������ǵ�һ�ε���ArticlesProvider�ӿڣ���ˣ���mProvidersByName��mProvidersByClass����Map�ж�������ArticlesProvider�������Ϣ����ˣ������ͨ��AppGlobals.getPackageManager���������PackageManagerService����ӿڣ�Ȼ��ֱ�ͨ������resolveContentProvider��getApplicationInfo�������ֱ��ȡArticlesProviderӦ�ó���������Ϣ���ֱ𱣴���cpi��cpr���������ر����С���Щ��Ϣ�����ڰ�װӦ�ó���Ĺ����б��������ģ�������Բο�AndroidӦ�ó���װ����Դ�������һ�ġ�

����ȥ��������жϵ�ǰҪ��ȡ��Content Provider�Ƿ������ڿͻ������м��أ����鿴һ�����Content Provider��������multiprocess����Ϊtrue����������ڿͻ������м��أ���ֱ�ӷ��������Content Provider����Ϣ�ˣ�

  1. if (r != null && cpr.canRunHere(r)) {
  2. // If this is a multiprocess provider, then just return its
  3. // info and allow the caller to instantiate it. Only do
  4. // this if the provider is the same user as the caller's
  5. // process, or can run as root (so can be in any process).
  6. return cpr;
  7. }
if (r != null && cpr.canRunHere(r)) { // If this is a multiprocess provider, then just return its // info and allow the caller to instantiate it. Only do // this if the provider is the same user as the caller's // process, or can run as root (so can be in any process). return cpr; }

����������龰�У�Ҫ��ȡ��ArticlesProvider������Ҫ�ڶ����Ľ��������У���ˣ���������ִ�У�

  1. // This is single process, and our app is now connecting to it.
  2. // See if we are already in the process of launching this
  3. // provider.
  4. final int N = mLaunchingProviders.size();
  5. int i;
  6. for (i=0; i<N; i++) {
  7. if (mLaunchingProviders.get(i) == cpr) {
  8. break;
  9. }
  10. }
// This is single process, and our app is now connecting to it. // See if we are already in the process of launching this // provider. final int N = mLaunchingProviders.size(); int i; for (i=0; i<N; i++) { if (mLaunchingProviders.get(i) == cpr) { break; } }

ϵͳ���������ڼ��ص�Content Provider��������mLaunchingProviders��Ա�����С��ڼ�����Ӧ��Content Provider֮ǰ������Ҫ�ж�һ�����ǿɷ����ڱ�����Ӧ�ó�����أ�����ǵĻ����Ͳ����ظ������ˡ�����������龰�У�û������Ӧ�ó���Ҳ���ڼ���ArticlesProvider���Content Provider��������ǰִ�У�

  1. // If the provider is not already being launched, then get it
  2. // started.
  3. if (i >= N) {
  4. final long origId = Binder.clearCallingIdentity();
  5. ProcessRecord proc = startProcessLocked(cpi.processName,
  6. cpr.appInfo, false, 0, "content provider",
  7. new ComponentName(cpi.applicationInfo.packageName,
  8. cpi.name), false);
  9. ......
  10. mLaunchingProviders.add(cpr);
  11. ......
  12. }
// If the provider is not already being launched, then get it // started. if (i >= N) { final long origId = Binder.clearCallingIdentity(); ProcessRecord proc = startProcessLocked(cpi.processName, cpr.appInfo, false, 0, "content provider", new ComponentName(cpi.applicationInfo.packageName, cpi.name), false); ...... mLaunchingProviders.add(cpr); ...... }

���������i >= NΪtrue���ͱ���û������Ӧ�ó������ڼ������Content Provider����ˣ���Ҫ����startProcessLocked����������һ���µĽ������������Content Provider��Ӧ�����ˣ�Ȼ���������ڼ��ص���Ϣ���ӵ�mLaunchingProviders��ȥ�������Ƚ��ŷ������������Ȼ�����������½����м���Content Provider�Ĺ��̣���������ִ�У�

  1. // Make sure the provider is published (the same provider class
  2. // may be published under multiple names).
  3. if (firstClass) {
  4. mProvidersByClass.put(cpi.name, cpr);
  5. }
  6. cpr.launchingApp = proc;
  7. mProvidersByName.put(name, cpr);
// Make sure the provider is published (the same provider class // may be published under multiple names). if (firstClass) { mProvidersByClass.put(cpi.name, cpr); } cpr.launchingApp = proc; mProvidersByName.put(name, cpr);

��δ�������Content Provider����Ϣ�ֱ𱣴浽mProvidersByName��mProviderByCalss����Map��ȥ���Է��������ѯ��

��Ϊ������Ҫ��ȡ��Content Provider�����µĽ����м��صģ���getContentProviderImpl�����������ϵͳ������ִ�еģ�������Ҫ�ȵ�Ҫ��ȡ��Content Provider�����µĽ����м�����ɺ���ܷ��أ��������漰������ͬ���������ˡ�����ʹ�õ�ͬ�������Dz��ϵ�ȥ������cpr��provider���Ƿ������ˡ���Ҫ��ȡ��Content Provider���µĽ��̼������֮������ͨ��Binder���̼�ͨ�Ż��Ƶ��õ�ϵͳ�����У������cpr������provider������Ϊ�Ѿ����غõ�Content Provider�ӿڣ���ʱ�򣬺���getContentProviderImpl�Ϳ��Է����ˡ�����Ĵ�����������ȴ�Ҫ��ȡ��Content Provider�����µĽ����м�����ɵģ�

  1. // Wait for the provider to be published...
  2. synchronized (cpr) {
  3. while (cpr.provider == null) {
  4. ......
  5. try {
  6. cpr.wait();
  7. } catch (InterruptedException ex) {
  8. }
  9. }
  10. }
// Wait for the provider to be published... synchronized (cpr) { while (cpr.provider == null) { ...... try { cpr.wait(); } catch (InterruptedException ex) { } } }

���������ٷ������½����м���ArticlesProvider���Content Provider�Ĺ��̡�

Step 8. ActivityManagerService.startProcessLocked

Step 9. Process.start

Step 10. ActivityThread.main

Step 11. ActivityThread.attach

Step 12. ActivityManagerService.attachApplication

���岽�DZ�׼��AndroidӦ�ó����������裬������Բο�AndroidӦ�ó�����������Դ�������һ���е�Step 23��Step 27������Androidϵͳ���½����������Զ��������̣�startService����ԭ������һ���е�Step 4��Step 9������Ͳ�����ϸ�����ˡ�

Step 13. ActivityManagerService.attachApplicationLocked

�������������frameworks/base/services/java/com/android/server/am/ActivityManagerService.java�ļ��У�

  1. public final class ActivityManagerService extends ActivityManagerNative
  2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  3. ......
  4. private final boolean attachApplicationLocked(IApplicationThread thread,
  5. int pid) {
  6. // Find the application record that is being attached... either via
  7. // the pid if we are running in multiple processes, or just pull the
  8. // next app record if we are emulating process with anonymous threads.
  9. ProcessRecord app;
  10. if (pid != MY_PID && pid >= 0) {
  11. synchronized (mPidsSelfLocked) {
  12. app = mPidsSelfLocked.get(pid);
  13. }
  14. } else if (mStartingProcesses.size() > 0) {
  15. ......
  16. } else {
  17. ......
  18. }
  19. ......
  20. app.thread = thread;
  21. app.curAdj = app.setAdj = -100;
  22. app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
  23. app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
  24. app.forcingToForeground = null;
  25. app.foregroundServices = false;
  26. app.debugging = false;
  27. ......
  28. boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
  29. List providers = normalMode ? generateApplicationProvidersLocked(app) : null;
  30. try {
  31. ......
  32. thread.bindApplication(processName, app.instrumentationInfo != null
  33. ? app.instrumentationInfo : app.info, providers,
  34. app.instrumentationClass, app.instrumentationProfileFile,
  35. app.instrumentationArguments, app.instrumentationWatcher, testMode,
  36. isRestrictedBackupMode || !normalMode,
  37. mConfiguration, getCommonServicesLocked());
  38. ......
  39. } catch (Exception e) {
  40. ......
  41. }
  42. ......
  43. return true;
  44. }
  45. ......
  46. private final List generateApplicationProvidersLocked(ProcessRecord app) {
  47. List providers = null;
  48. try {
  49. providers = AppGlobals.getPackageManager().
  50. queryContentProviders(app.processName, app.info.uid,
  51. STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS);
  52. } catch (RemoteException ex) {
  53. }
  54. if (providers != null) {
  55. final int N = providers.size();
  56. for (int i=0; i<N; i++) {
  57. ProviderInfo cpi =
  58. (ProviderInfo)providers.get(i);
  59. ContentProviderRecord cpr = mProvidersByClass.get(cpi.name);
  60. if (cpr == null) {
  61. cpr = new ContentProviderRecord(cpi, app.info);
  62. mProvidersByClass.put(cpi.name, cpr);
  63. }
  64. app.pubProviders.put(cpi.name, cpr);
  65. app.addPackage(cpi.applicationInfo.packageName);
  66. ensurePackageDexOpt(cpi.applicationInfo.packageName);
  67. }
  68. }
  69. return providers;
  70. }
  71. ......
  72. }
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... private final boolean attachApplicationLocked(IApplicationThread thread, int pid) { // Find the application record that is being attached... either via // the pid if we are running in multiple processes, or just pull the // next app record if we are emulating process with anonymous threads. ProcessRecord app; if (pid != MY_PID && pid >= 0) { synchronized (mPidsSelfLocked) { app = mPidsSelfLocked.get(pid); } } else if (mStartingProcesses.size() > 0) { ...... } else { ...... } ...... app.thread = thread; app.curAdj = app.setAdj = -100; app.curSchedGroup = Process.THREAD_GROUP_DEFAULT; app.setSchedGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE; app.forcingToForeground = null; app.foregroundServices = false; app.debugging = false; ...... boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info); List providers = normalMode ? generateApplicationProvidersLocked(app) : null; try { ...... thread.bindApplication(processName, app.instrumentationInfo != null ? app.instrumentationInfo : app.info, providers, app.instrumentationClass, app.instrumentationProfileFile, app.instrumentationArguments, app.instrumentationWatcher, testMode, isRestrictedBackupMode || !normalMode, mConfiguration, getCommonServicesLocked()); ...... } catch (Exception e) { ...... } ...... return true; } ...... private final List generateApplicationProvidersLocked(ProcessRecord app) { List providers = null; try { providers = AppGlobals.getPackageManager(). queryContentProviders(app.processName, app.info.uid, STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS); } catch (RemoteException ex) { } if (providers != null) { final int N = providers.size(); for (int i=0; i<N; i++) { ProviderInfo cpi = (ProviderInfo)providers.get(i); ContentProviderRecord cpr = mProvidersByClass.get(cpi.name); if (cpr == null) { cpr = new ContentProviderRecord(cpi, app.info); mProvidersByClass.put(cpi.name, cpr); } app.pubProviders.put(cpi.name, cpr); app.addPackage(cpi.applicationInfo.packageName); ensurePackageDexOpt(cpi.applicationInfo.packageName); } } return providers; } ...... }

������������Ǹ��ݴ������Ľ���ID�ҵ���Ӧ�Ľ��̼�¼�飬ע�⣬�������ID��Ӧ�ó���ArticlesProvider��ID��Ȼ���������̼�¼����һЩ����ʼ���Ĺ������ٽ�����ͨ������generateApplicationProvidersLocked�����Ҫ����������м��ص�Content Provider�б�������������龰�У���ֻ��ArticlesProvider���Content Provider�ˡ������ôӲ�����������IApplicationThread����thread��bindApplication������ִ��һЩӦ�ó����ʼ����������AndroidӦ�ó�����������Դ�������һ��������֪������Androidϵͳ�У�ÿһ��Ӧ�ó�����̶�������һ��ActivityThreadʵ���������ActivityThreadʵ�����棬��һ����Ա����mAppThread������һ��Binder��������ΪApplicationThread��ʵ����IApplicationThread�ӿڣ�����ר��������ActivityManagerService�������ͨ�ŵġ���ˣ�����������䣺

  1. thread.bindApplication(processName, app.instrumentationInfo != null
  2. ? app.instrumentationInfo : app.info, providers,
  3. app.instrumentationClass, app.instrumentationProfileFile,
  4. app.instrumentationArguments, app.instrumentationWatcher, testMode,
  5. isRestrictedBackupMode || !normalMode,
  6. mConfiguration, getCommonServicesLocked());
thread.bindApplication(processName, app.instrumentationInfo != null ? app.instrumentationInfo : app.info, providers, app.instrumentationClass, app.instrumentationProfileFile, app.instrumentationArguments, app.instrumentationWatcher, testMode, isRestrictedBackupMode || !normalMode, mConfiguration, getCommonServicesLocked());

�ͻ���뵽Ӧ�ó���ArticlesProvider�����е�ApplicationThread�����bindApplication������ȥ������������龰���������������������Ҫ�IJ������ǵ���������providers�ˣ���������Ҫ�����Ķ���

Step 14. ApplicationThread.bindApplication

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. private final class ApplicationThread extends ApplicationThreadNative {
  4. ......
  5. public final void bindApplication(String processName,
  6. ApplicationInfo appInfo, List<ProviderInfo> providers,
  7. ComponentName instrumentationName, String profileFile,
  8. Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher,
  9. int debugMode, boolean isRestrictedBackupMode, Configuration config,
  10. Map<String, IBinder> services) {
  11. if (services != null) {
  12. // Setup the service cache in the ServiceManager
  13. ServiceManager.initServiceCache(services);
  14. }
  15. AppBindData data = new AppBindData();
  16. data.processName = processName;
  17. data.appInfo = appInfo;
  18. data.providers = providers;
  19. data.instrumentationName = instrumentationName;
  20. data.profileFile = profileFile;
  21. data.instrumentationArgs = instrumentationArgs;
  22. data.instrumentationWatcher = instrumentationWatcher;
  23. data.debugMode = debugMode;
  24. data.restrictedBackupMode = isRestrictedBackupMode;
  25. data.config = config;
  26. queueOrSendMessage(H.BIND_APPLICATION, data);
  27. }
  28. ......
  29. }
  30. ......
  31. }
public final class ActivityThread { ...... private final class ApplicationThread extends ApplicationThreadNative { ...... public final void bindApplication(String processName, ApplicationInfo appInfo, List<ProviderInfo> providers, ComponentName instrumentationName, String profileFile, Bundle instrumentationArgs, IInstrumentationWatcher instrumentationWatcher, int debugMode, boolean isRestrictedBackupMode, Configuration config, Map<String, IBinder> services) { if (services != null) { // Setup the service cache in the ServiceManager ServiceManager.initServiceCache(services); } AppBindData data = new AppBindData(); data.processName = processName; data.appInfo = appInfo; data.providers = providers; data.instrumentationName = instrumentationName; data.profileFile = profileFile; data.instrumentationArgs = instrumentationArgs; data.instrumentationWatcher = instrumentationWatcher; data.debugMode = debugMode; data.restrictedBackupMode = isRestrictedBackupMode; data.config = config; queueOrSendMessage(H.BIND_APPLICATION, data); } ...... } ...... }

�����������ص���Ϣ����װ��һ��AppBindData����Ȼ����һ����Ϣ����ʽ���͵����̵߳���Ϣ������ȥ�ȵȴ������������Ϣ����������ActivityThread���handleBindApplication�����н��д����ġ�

Step 15. ActivityThread.handleBindApplication

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. private final void handleBindApplication(AppBindData data) {
  4. ......
  5. List<ProviderInfo> providers = data.providers;
  6. if (providers != null) {
  7. installContentProviders(app, providers);
  8. ......
  9. }
  10. ......
  11. }
  12. ......
  13. }
public final class ActivityThread { ...... private final void handleBindApplication(AppBindData data) { ...... List<ProviderInfo> providers = data.providers; if (providers != null) { installContentProviders(app, providers); ...... } ...... } ...... }

������������ݱȽ϶࣬���Ǻ����������޹صIJ��֣�ֻ��ע��Content Provider�йص��߼���������Ҫ���ǵ���installContentProviders�������ڱ��ذ�װContent Providers��Ϣ��

Step 16. ActivityThread.installContentProviders

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. private final void installContentProviders(
  4. Context context, List<ProviderInfo> providers) {
  5. final ArrayList<IActivityManager.ContentProviderHolder> results =
  6. new ArrayList<IActivityManager.ContentProviderHolder>();
  7. Iterator<ProviderInfo> i = providers.iterator();
  8. while (i.hasNext()) {
  9. ProviderInfo cpi = i.next();
  10. StringBuilder buf = new StringBuilder(128);
  11. buf.append("Pub ");
  12. buf.append(cpi.authority);
  13. buf.append(": ");
  14. buf.append(cpi.name);
  15. Log.i(TAG, buf.toString());
  16. IContentProvider cp = installProvider(context, null, cpi, false);
  17. if (cp != null) {
  18. IActivityManager.ContentProviderHolder cph =
  19. new IActivityManager.ContentProviderHolder(cpi);
  20. cph.provider = cp;
  21. results.add(cph);
  22. // Don't ever unload this provider from the process.
  23. synchronized(mProviderMap) {
  24. mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
  25. }
  26. }
  27. }
  28. try {
  29. ActivityManagerNative.getDefault().publishContentProviders(
  30. getApplicationThread(), results);
  31. } catch (RemoteException ex) {
  32. }
  33. }
  34. ......
  35. }
public final class ActivityThread { ...... private final void installContentProviders( Context context, List<ProviderInfo> providers) { final ArrayList<IActivityManager.ContentProviderHolder> results = new ArrayList<IActivityManager.ContentProviderHolder>(); Iterator<ProviderInfo> i = providers.iterator(); while (i.hasNext()) { ProviderInfo cpi = i.next(); StringBuilder buf = new StringBuilder(128); buf.append("Pub "); buf.append(cpi.authority); buf.append(": "); buf.append(cpi.name); Log.i(TAG, buf.toString()); IContentProvider cp = installProvider(context, null, cpi, false); if (cp != null) { IActivityManager.ContentProviderHolder cph = new IActivityManager.ContentProviderHolder(cpi); cph.provider = cp; results.add(cph); // Don't ever unload this provider from the process. synchronized(mProviderMap) { mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000)); } } } try { ActivityManagerNative.getDefault().publishContentProviders( getApplicationThread(), results); } catch (RemoteException ex) { } } ...... }

���������Ҫ�������������飬һ�ǵ���installProvider���ڱ��ذ�װÿһ��Content Proivder����Ϣ������Ϊÿһ��Content Provider����һ��ContentProviderHolder������������ص���Ϣ��ContentProviderHolder������һ��Binder������������Content Provider����Ϣ���ݸ�ActivityManagerService����ġ�����ЩContent Provider�����������Ժ󣬻�Ҫ����ActivityManagerService�����publishContentProviders������֪ͨActivityManagerService���������������Ҫ���ص�Content Provider�����Ѿ�׼������ˣ���ActivityManagerService�����publishContentProviders���������þ�������������ǰ��Step 7�ȴ����̵߳��ˡ�����������installProvider��ʵ�֣�Ȼ��������ActivityManagerService�����publishContentProviders������ʵ�֡�

Step 17. ActivityThread.installProvider

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. private final IContentProvider installProvider(Context context,
  4. IContentProvider provider, ProviderInfo info, boolean noisy) {
  5. ContentProvider localProvider = null;
  6. if (provider == null) {
  7. ......
  8. Context c = null;
  9. ApplicationInfo ai = info.applicationInfo;
  10. if (context.getPackageName().equals(ai.packageName)) {
  11. c = context;
  12. } else if (mInitialApplication != null &&
  13. mInitialApplication.getPackageName().equals(ai.packageName)) {
  14. c = mInitialApplication;
  15. } else {
  16. try {
  17. c = context.createPackageContext(ai.packageName,
  18. Context.CONTEXT_INCLUDE_CODE);
  19. } catch (PackageManager.NameNotFoundException e) {
  20. }
  21. }
  22. ......
  23. try {
  24. final java.lang.ClassLoader cl = c.getClassLoader();
  25. localProvider = (ContentProvider)cl.
  26. loadClass(info.name).newInstance();
  27. provider = localProvider.getIContentProvider();
  28. ......
  29. // XXX Need to create the correct context for this provider.
  30. localProvider.attachInfo(c, info);
  31. } catch (java.lang.Exception e) {
  32. ......
  33. }
  34. } else if (localLOGV) {
  35. ......
  36. }
  37. synchronized (mProviderMap) {
  38. // Cache the pointer for the remote provider.
  39. String names[] = PATTERN_SEMICOLON.split(info.authority);
  40. for (int i=0; i<names.length; i++) {
  41. ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
  42. localProvider);
  43. try {
  44. provider.asBinder().linkToDeath(pr, 0);
  45. mProviderMap.put(names[i], pr);
  46. } catch (RemoteException e) {
  47. return null;
  48. }
  49. }
  50. if (localProvider != null) {
  51. mLocalProviders.put(provider.asBinder(),
  52. new ProviderClientRecord(null, provider, localProvider));
  53. }
  54. }
  55. return provider;
  56. }
  57. ......
  58. }
public final class ActivityThread { ...... private final IContentProvider installProvider(Context context, IContentProvider provider, ProviderInfo info, boolean noisy) { ContentProvider localProvider = null; if (provider == null) { ...... Context c = null; ApplicationInfo ai = info.applicationInfo; if (context.getPackageName().equals(ai.packageName)) { c = context; } else if (mInitialApplication != null && mInitialApplication.getPackageName().equals(ai.packageName)) { c = mInitialApplication; } else { try { c = context.createPackageContext(ai.packageName, Context.CONTEXT_INCLUDE_CODE); } catch (PackageManager.NameNotFoundException e) { } } ...... try { final java.lang.ClassLoader cl = c.getClassLoader(); localProvider = (ContentProvider)cl. loadClass(info.name).newInstance(); provider = localProvider.getIContentProvider(); ...... // XXX Need to create the correct context for this provider. localProvider.attachInfo(c, info); } catch (java.lang.Exception e) { ...... } } else if (localLOGV) { ...... } synchronized (mProviderMap) { // Cache the pointer for the remote provider. String names[] = PATTERN_SEMICOLON.split(info.authority); for (int i=0; i<names.length; i++) { ProviderClientRecord pr = new ProviderClientRecord(names[i], provider, localProvider); try { provider.asBinder().linkToDeath(pr, 0); mProviderMap.put(names[i], pr); } catch (RemoteException e) { return null; } } if (localProvider != null) { mLocalProviders.put(provider.asBinder(), new ProviderClientRecord(null, provider, localProvider)); } } return provider; } ...... }

���������������Ҫ������Ӧ�ó�������а���Ӧ��Content Provider����ؽ����ˣ�������������龰�У�����Ҫ��ArticlesProvider���Ӧ�ó����а�ArticlesProvider���Content Provider����ص��ڴ������ˣ�

  1. final java.lang.ClassLoader cl = c.getClassLoader();
  2. localProvider = (ContentProvider)cl.
  3. loadClass(info.name).newInstance();
final java.lang.ClassLoader cl = c.getClassLoader(); localProvider = (ContentProvider)cl. loadClass(info.name).newInstance();

����ͨ������localProvider��getIContentProvider���������һ��Binder�������Binder���󷵻ظ�installContentProviders����֮�󣬾ͻᴫ��ActivityManagerService��ȥ����������Ӧ�ó������ͨ��������Binder����������Ӧ��Content Provider����ͨ�ŵ��ˡ������ȿ�һ�����������ʵ�֣�Ȼ���ٻص�installProvider�����м���������

Step 18. ContentProvider.getIContentProvider

�������������frameworks/base/core/java/android/content/ContentProvider.java�ļ��У�

  1. public abstract class ContentProvider implements ComponentCallbacks {
  2. ......
  3. private Transport mTransport = new Transport();
  4. ......
  5. class Transport extends ContentProviderNative {
  6. ......
  7. }
  8. public IContentProvider getIContentProvider() {
  9. return mTransport;
  10. }
  11. ......
  12. }
public abstract class ContentProvider implements ComponentCallbacks { ...... private Transport mTransport = new Transport(); ...... class Transport extends ContentProviderNative { ...... } public IContentProvider getIContentProvider() { return mTransport; } ...... }

���������ǿ��Կ�����ContentProvider���Transport��Ĺ�ϵ��������ActivityThread��ApplicationThread�Ĺ�ϵ������Ӧ�ó�����ֱ�ӵ���ContentProvider�ӿ��������������ݣ�����ͨ�����������ڲ�����mTransport����ӵ���ContentProvider�Ľӿڣ���һ����������һƪ�����з�������Content Provider�ӿ�����ȡ��������ʱ���ῴ����
�ص�ǰ���installProvider�����У�����������������ӿ�����ʼ���ոռ��غõ�Content Provider��

  1. // XXX Need to create the correct context for this provider.
  2. localProvider.attachInfo(c, info);
// XXX Need to create the correct context for this provider. localProvider.attachInfo(c, info);

ͬ���������Ƚ��뵽ContentProvider���attachInfo����ȥ��������ʵ�֣�Ȼ���ٻص�installProvider��������

Step 19. ContentProvider.attachInfo

�������������frameworks/base/core/java/android/content/ContentProvider.java�ļ��У�

  1. public abstract class ContentProvider implements ComponentCallbacks {
  2. ......
  3. public void attachInfo(Context context, ProviderInfo info) {
  4. /*
  5. * Only allow it to be set once, so after the content service gives
  6. * this to us clients can't change it.
  7. */
  8. if (mContext == null) {
  9. mContext = context;
  10. mMyUid = Process.myUid();
  11. if (info != null) {
  12. setReadPermission(info.readPermission);
  13. setWritePermission(info.writePermission);
  14. setPathPermissions(info.pathPermissions);
  15. mExported = info.exported;
  16. }
  17. ContentProvider.this.onCreate();
  18. }
  19. }
  20. ......
  21. }
public abstract class ContentProvider implements ComponentCallbacks { ...... public void attachInfo(Context context, ProviderInfo info) { /* * Only allow it to be set once, so after the content service gives * this to us clients can't change it. */ if (mContext == null) { mContext = context; mMyUid = Process.myUid(); if (info != null) { setReadPermission(info.readPermission); setWritePermission(info.writePermission); setPathPermissions(info.pathPermissions); mExported = info.exported; } ContentProvider.this.onCreate(); } } ...... }

��������ܼ򵥣���Ҫ���Ǹ������Content Provider����Ϣinfo��������Ӧ�Ķ�дȨ�ޣ�Ȼ��������������onCreate������������ִ��һЩ��ʼ���Ĺ���������������龰�У�����������ArticlesProvideӦ�ó����е�ArticlesProvider���ˡ�

Step 20. ArticlesProvider.onCreate

�������������ǰ��һƪ����AndroidӦ�ó������Content ProviderӦ��ʵ�����ܵ�Ӧ�ó���ArtilcesProviderԴ���빤��Ŀ¼�£����ļ�Ϊpackages/experimental/ArticlesProvider/src/shy/luo/providers/articles/ArticlesProvider.java�У�

  1. public class ArticlesProvider extends ContentProvider {
  2. ......
  3. @Override
  4. public boolean onCreate() {
  5. Context context = getContext();
  6. resolver = context.getContentResolver();
  7. dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION);
  8. return true;
  9. }
  10. ......
  11. }
public class ArticlesProvider extends ContentProvider { ...... @Override public boolean onCreate() { Context context = getContext(); resolver = context.getContentResolver(); dbHelper = new DBHelper(context, DB_NAME, null, DB_VERSION); return true; } ...... }

���������Ҫִ��һЩ�򵥵Ĺ��������磬���Ӧ�ó��������ĵ�ContentResolver�ӿںʹ������ݿ�����������󣬾�����Բο�ǰ��һƪ����AndroidӦ�ó������Content ProviderӦ��ʵ����

�ص�ǰ��Step 17�е�installProvider�����У������������ǰ���Щ�ڱ����м��ص�Content Provider��Ϣ���������ˣ��Է�������ѯ��ʹ�ã�

  1. synchronized (mProviderMap) {
  2. // Cache the pointer for the remote provider.
  3. String names[] = PATTERN_SEMICOLON.split(info.authority);
  4. for (int i=0; i<names.length; i++) {
  5. ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
  6. localProvider);
  7. try {
  8. provider.asBinder().linkToDeath(pr, 0);
  9. mProviderMap.put(names[i], pr);
  10. } catch (RemoteException e) {
  11. return null;
  12. }
  13. }
  14. if (localProvider != null) {
  15. mLocalProviders.put(provider.asBinder(),
  16. new ProviderClientRecord(null, provider, localProvider));
  17. }
  18. }
synchronized (mProviderMap) { // Cache the pointer for the remote provider. String names[] = PATTERN_SEMICOLON.split(info.authority); for (int i=0; i<names.length; i++) { ProviderClientRecord pr = new ProviderClientRecord(names[i], provider, localProvider); try { provider.asBinder().linkToDeath(pr, 0); mProviderMap.put(names[i], pr); } catch (RemoteException e) { return null; } } if (localProvider != null) { mLocalProviders.put(provider.asBinder(), new ProviderClientRecord(null, provider, localProvider)); } }

��ActivityMangerService���ƣ���ActivityThread�У���Content Provider��authorityΪ��ֵ�������Content Provider����Ϣ������mProviderMap��Ա�����У���Ϊһ��Content Provider���Զ�Ӧ���authority�����������һ��forѭ����������ͬʱ�������Content Provider��Ӧ��Binder����provider����ֵ�������Content Provider����Ϣ������mLocalProviders��Ա�����У���������һ���ڱ��ؼ��ص�Content Provider��

����installProviderִ������Ժ󣬷��ص�Step 16�е�instalContentProviders�����У�ִ��������䣺

  1. try {
  2. ActivityManagerNative.getDefault().publishContentProviders(
  3. getApplicationThread(), results);
  4. } catch (RemoteException ex) {
  5. }
try { ActivityManagerNative.getDefault().publishContentProviders( getApplicationThread(), results); } catch (RemoteException ex) { }

ǰ���Ѿ��ᵽ������������õ����þ���֪ͨActivityMangerService����Ҫ����������м��ص�Content Provider�Ѿ����������ˣ�����results�Ͱ�������Щ�Ѿ����غõ�Content Provider�ӿڡ�

Step 21. ActivityMangerService.publishContentProviders

�������������frameworks/base/services/java/com/android/server/am/ActivityManagerService.java�ļ��У�

  1. public final class ActivityManagerService extends ActivityManagerNative
  2. implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
  3. ......
  4. public final void publishContentProviders(IApplicationThread caller,
  5. List<ContentProviderHolder> providers) {
  6. ......
  7. synchronized(this) {
  8. final ProcessRecord r = getRecordForAppLocked(caller);
  9. ......
  10. final int N = providers.size();
  11. for (int i=0; i<N; i++) {
  12. ContentProviderHolder src = providers.get(i);
  13. if (src == null || src.info == null || src.provider == null) {
  14. continue;
  15. }
  16. ContentProviderRecord dst = r.pubProviders.get(src.info.name);
  17. if (dst != null) {
  18. mProvidersByClass.put(dst.info.name, dst);
  19. String names[] = dst.info.authority.split(";");
  20. for (int j = 0; j < names.length; j++) {
  21. mProvidersByName.put(names[j], dst);
  22. }
  23. int NL = mLaunchingProviders.size();
  24. int j;
  25. for (j=0; j<NL; j++) {
  26. if (mLaunchingProviders.get(j) == dst) {
  27. mLaunchingProviders.remove(j);
  28. j--;
  29. NL--;
  30. }
  31. }
  32. synchronized (dst) {
  33. dst.provider = src.provider;
  34. dst.app = r;
  35. dst.notifyAll();
  36. }
  37. ......
  38. }
  39. }
  40. }
  41. }
  42. ......
  43. }
public final class ActivityManagerService extends ActivityManagerNative implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { ...... public final void publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers) { ...... synchronized(this) { final ProcessRecord r = getRecordForAppLocked(caller); ...... final int N = providers.size(); for (int i=0; i<N; i++) { ContentProviderHolder src = providers.get(i); if (src == null || src.info == null || src.provider == null) { continue; } ContentProviderRecord dst = r.pubProviders.get(src.info.name); if (dst != null) { mProvidersByClass.put(dst.info.name, dst); String names[] = dst.info.authority.split(";"); for (int j = 0; j < names.length; j++) { mProvidersByName.put(names[j], dst); } int NL = mLaunchingProviders.size(); int j; for (j=0; j<NL; j++) { if (mLaunchingProviders.get(j) == dst) { mLaunchingProviders.remove(j); j--; NL--; } } synchronized (dst) { dst.provider = src.provider; dst.app = r; dst.notifyAll(); } ...... } } } } ...... }

����������龰�У�ֻ��һ��Content Provider����ˣ������N�ȴ�1�����м��forѭ�����棬����Ҫ�������������䣺

  1. ContentProviderRecord dst = r.pubProviders.get(src.info.name);
ContentProviderRecord dst = r.pubProviders.get(src.info.name);

������õ���ContentProviderRecord����dst��������ǰ��Step 7�д�����ContentProviderRecord����cpr�ˡ���forѭ���У������ǰ����Content Provider��Ϣ�������mProvidersByClass��mProvidersByName�У�

  1. mProvidersByClass.put(dst.info.name, dst);
  2. String names[] = dst.info.authority.split(";");
  3. for (int j = 0; j < names.length; j++) {
  4. mProvidersByName.put(names[j], dst);
  5. }
mProvidersByClass.put(dst.info.name, dst); String names[] = dst.info.authority.split(";"); for (int j = 0; j < names.length; j++) { mProvidersByName.put(names[j], dst); }

ǰ���Ѿ�˵����������Map�У�һ����������Ϊ��ֵ����Content Provider��Ϣ��һ������authorityΪ��ֵ����Content Provider��Ϣ��

��Ϊ���Content Provider�Ѿ����غ��ˣ���ˣ�������mLaunchingProviders�б���ɾ����

  1. int NL = mLaunchingProviders.size();
  2. int j;
  3. for (j=0; j<NL; j++) {
  4. if (mLaunchingProviders.get(j) == dst) {
  5. mLaunchingProviders.remove(j);
  6. j--;
  7. NL--;
  8. }
  9. }
int NL = mLaunchingProviders.size(); int j; for (j=0; j<NL; j++) { if (mLaunchingProviders.get(j) == dst) { mLaunchingProviders.remove(j); j--; NL--; } }

����������ContentProviderRecord����dst��provider��Ϊ�Ӳ�����������Content ProviderԶ�̽ӿڣ�

  1. synchronized (dst) {
  2. dst.provider = src.provider;
  3. dst.app = r;
  4. dst.notifyAll();
  5. }
synchronized (dst) { dst.provider = src.provider; dst.app = r; dst.notifyAll(); }

ִ����dst.notiryAll������Step 7�еȴ�Ҫ��ȡ��Content Provider�ӿڼ�����ϵ��߳̾ͱ������ˡ�����֮������鱾��ContentProviderRecord����cpr��provider��Ϊnull�����Ǿͷ����ˡ������շ��ص�Step 5�е�ActivityThread���getProvider�����У���������ִ�У�

  1. IContentProvider prov = installProvider(context, holder.provider,
  2. holder.info, true);
IContentProvider prov = installProvider(context, holder.provider, holder.info, true);

ע�⣬��������ArticleӦ�ó����н�����ִ��installProvider�����ģ���ǰ���Step 17��installProvider��������ArticlesProviderӦ�ó��������ִ�еġ�

Step 22. ActivityThread.installProvider

�������������frameworks/base/core/java/android/app/ActivityThread.java�ļ��У�

  1. public final class ActivityThread {
  2. ......
  3. private final IContentProvider installProvider(Context context,
  4. IContentProvider provider, ProviderInfo info, boolean noisy) {
  5. ......
  6. if (provider == null) {
  7. ......
  8. } else if (localLOGV) {
  9. ......
  10. }
  11. synchronized (mProviderMap) {
  12. // Cache the pointer for the remote provider.
  13. String names[] = PATTERN_SEMICOLON.split(info.authority);
  14. for (int i=0; i<names.length; i++) {
  15. ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
  16. localProvider);
  17. try {
  18. provider.asBinder().linkToDeath(pr, 0);
  19. mProviderMap.put(names[i], pr);
  20. } catch (RemoteException e) {
  21. return null;
  22. }
  23. }
  24. ......
  25. }
  26. return provider;
  27. }
  28. ......
  29. }
public final class ActivityThread { ...... private final IContentProvider installProvider(Context context, IContentProvider provider, ProviderInfo info, boolean noisy) { ...... if (provider == null) { ...... } else if (localLOGV) { ...... } synchronized (mProviderMap) { // Cache the pointer for the remote provider. String names[] = PATTERN_SEMICOLON.split(info.authority); for (int i=0; i<names.length; i++) { ProviderClientRecord pr = new ProviderClientRecord(names[i], provider, localProvider); try { provider.asBinder().linkToDeath(pr, 0); mProviderMap.put(names[i], pr); } catch (RemoteException e) { return null; } } ...... } return provider; } ...... }

ͬ����ִ��installProvider��������Step 17��ͬ�����ﴫ�����IJ���provider�Dz�Ϊnull�ģ���ˣ�������Ҫִ���ڱ��ؼ���Content Provider�Ĺ�����ֻ��Ҫ�Ѵ�ActivityMangerService�л�õ�Content Provider�ӿڱ����ڳ�Ա����mProviderMap�оͿ����ˡ�

��������ȡ��"shy.luo.providers.artilces"���uri��Ӧ��Content Provider��shy.luo.providers.articles.ArticlesProvider��������ˣ���ͬʱҲ������Content Provider���������̡�������Ӧ�ó����������Content Provider�Ľӿ�֮�󣬾Ϳ��Է���������Ĺ��������ˡ�������һƪ�����У����ǽ��ص����AndroidӦ�ó������Content Provider�ڲ�ͬ�����д������ݵĹ��̣���Content Provider�ڲ�ͬӦ�ó����й������ݵ�ԭ���������ע��

 

����ת�ԣ�http://blog.csdn.net/luoshengyang/article/details/6963418

 

��������
��������(0)
���� *
�������� *
��֤�� *ͼƬ�����壿������µõ���֤��