美文网首页
Android Framework——Content Provi

Android Framework——Content Provi

作者: Peakmain | 来源:发表于2021-05-11 16:15 被阅读0次

启动过程源码分析

官方案例


image.png

getContentResolver源码

    @Override
    public ContentResolver getContentResolver() {
          //mContentResolver实际是ApplicationContentResolver
        return mContentResolver;
    }
    public final @Nullable Cursor query(final @RequiresPermission.Read @NonNull Uri uri,
            @Nullable String[] projection, @Nullable Bundle queryArgs,
            @Nullable CancellationSignal cancellationSignal) {
        Preconditions.checkNotNull(uri, "uri");
         //返回IContentProvider 对象
        IContentProvider unstableProvider = acquireUnstableProvider(uri);
        try {
            try {
                qCursor = unstableProvider.query(mPackageName, uri, projection,
                        queryArgs, remoteCancellationSignal);
            } 
        }
    }


查看acquireUnstableProvider源码

    public final IContentProvider acquireUnstableProvider(Uri uri) {
           //检查scheme是否等于content
        if (!SCHEME_CONTENT.equals(uri.getScheme())) {
            return null;
        }
        String auth = uri.getAuthority();
        if (auth != null) {
            return acquireUnstableProvider(mContext, uri.getAuthority());
        }
        return null;
    }
   //实现类实际是ContextImpl类的ApplicationContentResolver
   protected abstract IContentProvider acquireUnstableProvider(Context c, String name);
   private static final class ApplicationContentResolver extends ContentResolver {
           @Override
        protected IContentProvider acquireUnstableProvider(Context c, String auth) {
             //mMainThread实际是ActivityThread
            return mMainThread.acquireProvider(c,
                    ContentProvider.getAuthorityWithoutUserId(auth),
                    resolveUserIdFromAuthority(auth), false);
        }
}
    public final IContentProvider acquireProvider(
            Context c, String auth, int userId, boolean stable) {
        final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
        if (provider != null) {
           //判断provider是否为空
            return provider;
        }
        ContentProviderHolder holder = null;
        try {
            synchronized (getGetProviderLock(auth, userId)) {
                 //实际最终会走到AMS的getContentProvider方法
                holder = ActivityManager.getService().getContentProvider(
                        getApplicationThread(), auth, userId, stable);
            }
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        if (holder == null) {
            Slog.e(TAG, "Failed to find provider info for " + auth);
            return null;
        }
         //返回的ContentProvider相关的数据存储在mProviderMap中
        holder = installProvider(c, holder, holder.info,
                true /*noisy*/, holder.noReleaseNeeded, stable);
        return holder.provider;
    }
    @Override
    public final ContentProviderHolder getContentProvider(
            IApplicationThread caller, String name, int userId, boolean stable) {
        enforceNotIsolatedCaller("getContentProvider");
        return getContentProviderImpl(caller, name, null, stable, userId);
    }
private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
            String name, IBinder token, boolean stable, int userId) {
       if (i >= N) {
                    try {
                      //获取ContentProvider的进程信息
                        ProcessRecord proc = getProcessRecordLocked(
                                cpi.processName, cpr.appInfo.uid, false);
                        if (proc != null && proc.thread != null && !proc.killed) {
                            //如果已经启动就会走到这里
                            if (!proc.pubProviders.containsKey(cpi.name)) {
                                checkTime(startTime, "getContentProviderImpl: scheduling install");
                                proc.pubProviders.put(cpi.name, cpr);
                                try {
                                    proc.thread.scheduleInstallProvider(cpi);
                                } catch (RemoteException e) {
                                }
                            }
                        } else {
                            //如果没有启动则进入这里
                            proc = startProcessLocked(cpi.processName,
                                    cpr.appInfo, false, 0, "content provider",
                                    new ComponentName(cpi.applicationInfo.packageName,
                                            cpi.name), false, false, false);
                        }
                        cpr.launchingApp = proc;
                        mLaunchingProviders.add(cpr);
                    } finally {
                        Binder.restoreCallingIdentity(origId);
                    }
                }
    }

刚开始肯定是没有创建进程,startProcessLocked最后走到的ActivityThread的main方法

    public static void main(String[] args) {
            //创建looper
        Looper.prepareMainLooper();
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);
        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
       //消息循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }
  private void attach(boolean system) {
   //得到AMS服务
    final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
              //调用AMS的attachApplication方法
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }   
}

AMS启动ContentProvider

    @Override
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }
    private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
             thread.bindApplication(processName, appInfo, providers,
                        app.instr.mClass,
                        profilerInfo, app.instr.mArguments,
                        app.instr.mWatcher,
                        app.instr.mUiAutomationConnection, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, isAutofillCompatEnabled);
}

从上面传值我们可以知道thread实际是ApplicationThread

    private class ApplicationThread extends IApplicationThread.Stub {
        public final void bindApplication(String processName, ApplicationInfo appInfo,
                List<ProviderInfo> providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
              sendMessage(H.BIND_APPLICATION, data);
        }
}
case BIND_APPLICATION:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
 break;
private void handleBindApplication(AppBindData data) {
      //创建ContextImpl对象
    final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
  if (ii != null) {
            try {
                final ClassLoader cl = instrContext.getClassLoader();
              //通过反射创建mInstrumentation 对象
                mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
            } catch (Exception e) {
           
            }

            final ComponentName component = new ComponentName(ii.packageName, ii.name);
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        } else {
            mInstrumentation = new Instrumentation();
            mInstrumentation.basicInit(this);
        }
            //创建application
        app = data.info.makeApplication(data.restrictedBackupMode, null);
         if (!data.restrictedBackupMode) {
                if (!ArrayUtils.isEmpty(data.providers)) {
                   //启动contentProviders
                    installContentProviders(app, data.providers);
                    mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
                }
            }
         try {
                //调用Application的onCreate方法
               mInstrumentation.onCreate(data.instrumentationArgs);
            }
     }
}

我们会发现contentProvider所在的应用程序进程实在Application的onCreate之前调用的。我们继续分析installContentProviders的源码

    private void installContentProviders(
            Context context, List<ProviderInfo> providers) {
        final ArrayList<ContentProviderHolder> results = new ArrayList<>();

        for (ProviderInfo cpi : providers) {
            ContentProviderHolder cph = installProvider(context, null, cpi,
                    false /*noisy*/, true /*noReleaseNeeded*/, true /*stable*/);
        }
        try {
            ActivityManager.getService().publishContentProviders(
                getApplicationThread(), results);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
    }
    private ContentProviderHolder installProvider(Context context,
            ContentProviderHolder holder, ProviderInfo info,
            boolean noisy, boolean noReleaseNeeded, boolean stable) {
        ContentProvider localProvider = null;
        IContentProvider provider;
        if (holder == null || holder.provider == null) {
           //创建context
            try {
                final java.lang.ClassLoader cl = c.getClassLoader();
                  //创建localProvider对象
                provider = localProvider.getIContentProvider();
                if (provider == null) {
                    return null;
                }
                localProvider.attachInfo(c, info);
            }
        return retHolder;
    }
    public void attachInfo(Context context, ProviderInfo info) {
        attachInfo(context, info, false);
    }
    private void attachInfo(Context context, ProviderInfo info, boolean testing) {
            //调用ContentProvider的onCreate生命周期
            ContentProvider.this.onCreate();
        }
    }
ContentProvider的启动过程.png

相关文章

网友评论

      本文标题:Android Framework——Content Provi

      本文链接:https://www.haomeiwen.com/subject/nmogdltx.html