源码 ContentProvider 的创建过程

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/
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值