源码 ContentProvider 的创建过程

来源:互联网 发布:损坏视频修复软件 编辑:程序博客网 时间:2024/05/16 18:06
ContentProvider # 
当应用启动时,入口方法 为 ActivityThread 的main ,
1、 在main 方法中 创建 ActivityThread 的实例 并创建主线程的消息队列
2、 在 ActivityThread 的 attach 方法中会远程调用 AMS 的 attachApplicationLocked 方法
  并将 ApplicationThread 对象提供给 AMS
3、 ApplicationThread 是一个 Binder 对象,他的 Binder 接口是 IApplication
  主要用于 ActivityThread 和 AMS 的通信
4、在 AMS 的 attachApplicationLocked 方法中,会调用 Applicationthread 的 bindApplication,
  这个过程同样跨进程完成的,
5、bindApplication 的逻辑经过 ActivityThread 中 mH 切换到  ActivityThread 中的 
   handerBindApplication  方法,handerBindApplication 会创建 Application  对象
  并加载 ContentProvider


ActivityThread  #  main  , attach      
public static void main(String[] args) {        Looper.prepareMainLooper();    ActivityThread thread = new ActivityThread();    thread.attach(false);    if (sMainThreadHandler == null) {        sMainThreadHandler = thread.getHandler();    }    AsyncTask.init();    if (false) {        Looper.myLooper().setMessageLogging(new                LogPrinter(Log.DEBUG, "ActivityThread"));    }    Looper.loop();    throw new RuntimeException("Main thread loop unexpectedly exited");}private void attach(boolean system) {    sCurrentActivityThread = this;    mSystemThread = system;    if (!system) {        ViewRootImpl.addFirstDrawHandler(new Runnable() {            @Override            public void run() {                ensureJitEnabled();            }        });        android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",                UserHandle.myUserId());        RuntimeInit.setApplicationObject(mAppThread.asBinder());        final IActivityManager mgr = ActivityManagerNative.getDefault();        try {            mgr.attachApplication(mAppThread);        } catch (RemoteException ex) {            // Ignore        }
AMS  #  attachApplicationLocked  
private final boolean attachApplicationLocked(IApplicationThread thread,                                              int pid) {    try {        。。。        thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,                profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,                app.instrumentationUiAutomationConnection, testMode, enableOpenGlTrace,                isRestrictedBackupMode || !normalMode, app.persistent,                new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),                mCoreSettingsObserver.getCoreSettingsLocked());        updateLruProcessLocked(app, false, null);        app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();    } catch (Exception e) {        // todo: Yikes!  What should we do?  For now we will try to        // start another process, but that could easily get us in        // an infinite loop of restarting processes...        Slog.wtf(TAG, "Exception thrown during bind of " + app, e);        app.resetPackageList(mProcessStats);        app.unlinkDeathRecipient();        startProcessLocked(app, "bind fail", processName);        return false;    }    }

ActivityThread  #  bindApplication

public final void bindApplication(String processName, ApplicationInfo appInfo,                                  List<ProviderInfo> providers, ComponentName instrumentationName,                                  ProfilerInfo profilerInfo, Bundle instrumentationArgs,                                  IInstrumentationWatcher instrumentationWatcher,                                  IUiAutomationConnection instrumentationUiConnection, int debugMode,                                  boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,                                  Configuration config, CompatibilityInfo compatInfo, Map<String, IBinder> services,                                  Bundle coreSettings) {        IPackageManager pm = getPackageManager();    android.content.pm.PackageInfo pi = null;    try {        pi = pm.getPackageInfo(appInfo.packageName, 0, UserHandle.myUserId());    } catch (RemoteException e) {    }    if (pi != null) {        boolean sharedUserIdSet = (pi.sharedUserId != null);        boolean processNameNotDefault =                (pi.applicationInfo != null &&                        !appInfo.packageName.equals(pi.applicationInfo.processName));        boolean sharable = (sharedUserIdSet || processNameNotDefault);        // Tell the VMRuntime about the application, unless it is shared        // inside a process.        if (!sharable) {            VMRuntime.registerAppInfo(appInfo.packageName, appInfo.dataDir,                    appInfo.processName);        }    }       sendMessage(H.BIND_APPLICATION, data);}
ActivityThread  #  handleBindApplication
private void handleBindApplication(AppBindData data) {        /**     * Initialize the default http proxy in this process for the reasons we set the time zone.     */    IBinder b = ServiceManager.getService(Context.CONNECTIVITY_SERVICE);    if (data.instrumentationName != null) {        InstrumentationInfo ii = null;         ii = appContext.getPackageManager().                    getInstrumentationInfo(data.instrumentationName, 0);  .....        LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,                appContext.getClassLoader(), false, true, false);        ContextImpl instrContext = ContextImpl.createAppContext(this, pi);        try {            java.lang.ClassLoader cl = instrContext.getClassLoader();            mInstrumentation = (Instrumentation)                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();        } catch (Exception e) {                  }        mInstrumentation.init(this, instrContext, appContext,                new ComponentName(ii.packageName, ii.name), data.instrumentationWatcher,                data.instrumentationUiAutomationConnection);     try {        Application app = data.info.makeApplication(data.restrictedBackupMode, null);        mInitialApplication = app;        // don't bring up providers in restricted mode; they may depend on the        // app's custom Application class        if (!data.restrictedBackupMode) {            List<ProviderInfo> providers = data.providers;            if (providers != null) {                installContentProviders(app, providers);                // For process that contains content providers, we want to                // ensure that the JIT is enabled "at some point".                mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);            }        }        try {            mInstrumentation.onCreate(data.instrumentationArgs);        }        catch (Exception e) {            throw new RuntimeException(                    "Exception thrown in onCreate() of "                            + data.instrumentationName + ": " + e.toString(), e);        }        try {            mInstrumentation.callApplicationOnCreate(app);        } catch (Exception e) {            if (!mInstrumentation.onException(app, e)) {                throw new RuntimeException(                        "Unable to create application " + app.getClass().getName()                                + ": " + e.toString(), e);            }        }    } finally {        StrictMode.setThreadPolicy(savedPolicy);    }}}
ActivityThread  #  installContentProviders # installProviders
private IActivityManager.ContentProviderHolder installProvider(Context context,                                                               IActivityManager.ContentProviderHolder holder, ProviderInfo info,                                                               boolean noisy, boolean noReleaseNeeded, boolean stable) {    ContentProvider localProvider = null;    IContentProvider provider;           try {            final java.lang.ClassLoader cl = c.getClassLoader();            localProvider = (ContentProvider)cl.                    loadClass(info.name).newInstance();            provider = localProvider.getIContentProvider();            if (provider == null) {                Slog.e(TAG, "Failed to instantiate class " +                        info.name + " from sourceDir " +                        info.applicationInfo.sourceDir);                return null;            }            if (DEBUG_PROVIDER) Slog.v(                    TAG, "Instantiating local provider " + info.name);            // XXX Need to create the correct context for this provider.            localProvider.attachInfo(c, info);
ContentProvider # attachInfo
private void attachInfo(Context context, ProviderInfo info, boolean testing) {    mNoPerms = testing;    /*     * 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;        if (context != null) {            mTransport.mAppOpsManager = (AppOpsManager) context.getSystemService(                    Context.APP_OPS_SERVICE);        }        mMyUid = Process.myUid();        if (info != null) {            setReadPermission(info.readPermission);            setWritePermission(info.writePermission);            setPathPermissions(info.pathPermissions);            mExported = info.exported;            mSingleUser = (info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0;            setAuthorities(info.authority);        }        ContentProvider.this.onCreate();    }}
Android API :http://www.android-doc.com/reference/packages.html 
http://tool.oschina.net/uploads/apidocs/android/reference/packages.html 
Android 源码:http://androidxref.com/