App启动时Application初始化详解

参考博文: http://www.jianshu.com/p/6037f6fda285

App的ActivityThread与Application详解

一个App的程序入口到底是什么?
ActivityThread.main(),每一个App应用都是由AMS通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的进程,然后在调用ActivityThread类中的main方法开始的。当Application创建完成之后,AMS会通过Binder机制通知ActivityThread去创建需要的Activity了。最后会辗转到Instrumentation来创建Activity。

整个App的主线程的消息循环是在哪里创建的?
是在ActivityThread初始化的时候,就已经创建消息循环了,所以在主线程里面创建Handler不需要指定Looper,而如果在其他线程使用Handler,则需要单独使用Looper.prepare()和Looper.loop()创建消息循环。

    public static void main(String[] args) {

          ...ignore some code...    
        //初始化Looper
        Looper.prepareMainLooper();
        //创建一个APP主线程ActivityThread对象
        ActivityThread thread = new ActivityThread();
        //初始化App应用信息
        thread.attach(false);

        if (sMainThreadHandler == null) {
        //获得主线程也就是UI线程的handler对象
            sMainThreadHandler = thread.getHandler();
        }

        AsyncTask.init();

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }
        //启动Looper循环,进入消息循环。
        Looper.loop();

          ...ignore some code...    

 }

Application是在什么时候创建的?onCreate()什么时候调用的?

也是在ActivityThread.main()的时候,再具体点呢,就是在thread.attach(false)的时候。

我们先看一下ActivityThread.attach():

private void attach(boolean system) {
        sCurrentActivityThread = this;
        mSystemThread = system;
        //普通App进这里
        if (!system) {

            ...ignore some code...    

            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            //对ActivityManagerProxy实例化
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
            //调用ActivityManagerProxy中attachApplication方法进行Binder交互
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                // Ignore
            }
           } else {
             //这个分支在SystemServer加载的时候会进入,通过调用
             // private void createSystemContext() {
             //    ActivityThread activityThread = ActivityThread.systemMain();
             //} 

             // public static ActivityThread systemMain() {
        //        if (!ActivityManager.isHighEndGfx()) {
        //            HardwareRenderer.disable(true);
        //        } else {
        //            HardwareRenderer.enableForegroundTrimming();
        //        }
        //        ActivityThread thread = new ActivityThread();
        //        thread.attach(true);
        //        return thread;
        //    }  
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
                }     
           }
    }

这里的mgr.attachApplication(mAppThread)就是ActivityManagerProxy.attachApplication()进行Binder交互:

    public void attachApplication(IApplicationThread app) throws RemoteException
    {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IActivityManager.descriptor);
        data.writeStrongBinder(app.asBinder());
        mRemote.transact(ATTACH_APPLICATION_TRANSACTION, data, reply, 0);
        reply.readException();
        data.recycle();
        reply.recycle();
    }

ActivityManagerNative.onTransact响应调用AMS中的attachApplication()方法:

        case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }

AMS的attachApplication方法中调用attachApplicationLocked:

@Override
    public final void attachApplication(IApplicationThread thread) {
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final long origId = Binder.clearCallingIdentity();
            attachApplicationLocked(thread, callingPid);
            Binder.restoreCallingIdentity(origId);
        }
    }

然后就是

 private final boolean attachApplicationLocked(IApplicationThread thread,
            int pid) {


             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());
            }

thread是IApplicationThread,实际上就是ApplicationThread在服务端的代理类ApplicationThreadProxy,然后又通过IPC就会调用到ApplicationThread的对应方法

private class ApplicationThread extends ApplicationThreadNative {

  public final void bindApplication(String processName, ApplicationInfo appInfo,
                List providers, ComponentName instrumentationName,
                ProfilerInfo profilerInfo, Bundle instrumentationArgs,
                IInstrumentationWatcher instrumentationWatcher,
                IUiAutomationConnection instrumentationUiConnection, int debugMode,
                boolean enableOpenGlTrace, boolean isRestrictedBackupMode, boolean persistent,
                Configuration config, CompatibilityInfo compatInfo, Map services,
                Bundle coreSettings) {

                 ...ignore some code...    

             AppBindData data = new AppBindData();
            data.processName = processName;
            data.appInfo = appInfo;
            data.providers = providers;
            data.instrumentationName = instrumentationName;
            data.instrumentationArgs = instrumentationArgs;
            data.instrumentationWatcher = instrumentationWatcher;
            data.instrumentationUiAutomationConnection = instrumentationUiConnection;
            data.debugMode = debugMode;
            data.enableOpenGlTrace = enableOpenGlTrace;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            sendMessage(H.BIND_APPLICATION, data);

我们需要关注的其实就是最后的sendMessage(),里面有函数的编号H.BIND_APPLICATION,然后这个Messge会被H这个Handler处理:

private class H extends Handler {

      ...ignore some code... 

     public static final int BIND_APPLICATION        = 110;

    ...ignore some code... 

     public void handleMessage(Message msg) {
          switch (msg.what) {
        ...ignore some code... 
         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;
        ...ignore some code... 
        }
 }

在handleBindApplication(data)中通过data.info.makeApplication进行makeApplication实例化,在mInstrumentation.callApplicationOnCreate实现了Application的onCreate()的调用:

private void handleBindApplication(AppBindData data) {

 try {

           ...ignore some code... 
            //这里进行Application实例化
            Application app = data.info.makeApplication(data.restrictedBackupMode, null);
            mInitialApplication = app;

           ...ignore some code... 

            try {
                mInstrumentation.onCreate(data.instrumentationArgs);
            }
            catch (Exception e) {
            }
            try {
            //这里开始调用Application的OnCreate()生命周期
                mInstrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {            }
        } finally {
            StrictMode.setThreadPolicy(savedPolicy);
        }
 }

data.info是一个LoadeApk对象。
LoadeApk.makeApplication():

 public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        //第一次进来mApplication==null条件不满足,之后创建Activity的时候条件满足直接返回当前Application对象
        if (mApplication != null) {
            return mApplication;
        }

        Application app = null;

        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
            appClass = "android.app.Application";
        }

        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                initializeJavaContextClassLoader();
            }
            //为Appliaction创建ContextImpl对象
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            //调用Instrumentation类中的newApplication方法创建Application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;

    //传进来的是null,所以这里不会执行,onCreate在上一层执行
        if (instrumentation != null) {
            try {
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {

所以最后还是通过Instrumentation.makeApplication()实例化的,而且通过反射拿到Application对象之后,直接调用attach(),所以attach()调用是在onCreate()之前的:

static public Application newApplication(Class clazz, Context context)
            throws InstantiationException, IllegalAccessException, 
            ClassNotFoundException {
        Application app = (Application)clazz.newInstance();
        app.attach(context);
        return app;
    }

附上两副图,帮助你更好了解过程及原理:

Activity Thread与AMS进行Binder交互的原理图:

App启动时Application初始化详解_第1张图片

Application初始化过程时序图:

App启动时Application初始化详解_第2张图片

你可能感兴趣的:(Android学习)