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<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) {

                 ...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交互的原理图:

Application初始化过程时序图:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值