Application的启动过程(源码)

Application 对象的生命周期是整个程序中最长的,即等于Android App的生命周期。

Applicaiton类的应用场景

  • 初始化应用程序级别的资源,如全局对象、环境配置变量等
  • 数据共享、数据缓存,如设置全局共享变量、方法等
  • 获取应用程序当前的内存使用情况,及时释放资源,从而避免被系统杀死

以前我们说过,应用程序的主入口是ActivityThread#main(),Application也是在这里实例化的,直接上源码吧!这里的源码是省略过的哈,比如说main里面的Looper初始化和循环都没了。

ActivityThread#main()

public static void main(String[] args) {
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
    }
复制代码

ActivityThread#attach()

mAppThread是一个ApplicationThread对象,ApplicationThread是Application的内部类,mAppThread是在ActivityThread类初始化的时候创建的。

 private void attach(boolean system) {
        if (!system) {
            final IActivityManager mgr = ActivityManager.getService();
            try {
                mgr.attachApplication(mAppThread); //mAppThread是一个ApplicationThread对象
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
            // 省略GC线程,监控堆栈
            });
        } //省略else和configurationChanged部分
    }
复制代码

ActivityManager#getService() 是怎么得到远端服务的呢?

重点来了,还记得我们之前说Binder机制么?没看过的可以查看下,Binder机制总结

Binder机制分为client、server、serviceManager。

1、server需要向serviceManager注册服务;

2、client需要从serviceManager查询服务;

3、client根据查询到的服务,就可以间接的调用远端服务啦

这里恰恰是步骤2,client根据注册的服务名,获取到AMS的一个引用 (ActivityManagerService)

ActivityManager#getService()

 public static IActivityManager getService() {
        return IActivityManagerSingleton.get();
    }

    private static final Singleton<IActivityManager> IActivityManagerSingleton =
            new Singleton<IActivityManager>() {
                @Override
                protected IActivityManager create() {
                    final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
                    final IActivityManager am = IActivityManager.Stub.asInterface(b);
                    return am;
                }
            };
复制代码

ActivityManagerService#attachApplication()

@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) {
//省略一大段代码
            if (app.instr != null) {
                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);
            } else {
                thread.bindApplication(processName, appInfo, providers, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.persistent,
                        new Configuration(getGlobalConfiguration()), app.compat,
                        getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial);
            }
//继续省略一大段代码
    }
复制代码

ApplicationThread#bindApplication()

前面我们说ApplicationThread是ActivityThread的一个内部类

ApplicationThread#bindApplication()会通过mH发送一个H.BIND_APPLICATION的消息

mH是一个Handler对象,在ActivityThread初始化的时候创建的,Handler机制之前我们也说过的,可以自行查阅

public final void bindApplication(xxxxxxxxx) {

        //对入参的各种赋值,包装成一个AppBindData对象
            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.enableBinderTracking = enableBinderTracking;
            data.trackAllocation = trackAllocation;
            data.restrictedBackupMode = isRestrictedBackupMode;
            data.persistent = persistent;
            data.config = config;
            data.compatInfo = compatInfo;
            data.initProfilerInfo = profilerInfo;
            data.buildSerial = buildSerial;
            sendMessage(H.BIND_APPLICATION, data);
        }
        
        private void sendMessage(int what, Object obj) {
        sendMessage(what, obj, 0, 0, false);
    }
    
    private void sendMessage(int what, Object obj, int arg1, int arg2, boolean async) {
        Message msg = Message.obtain();
        msg.what = what;
        msg.obj = obj;
        msg.arg1 = arg1;
        msg.arg2 = arg2;
        mH.sendMessage(msg);
    }
    
    final H mH = new H();
复制代码

接下来我们看下H是怎么处理这个H.BIND_APPLICATION消息的。

private class H extends Handler {
 //省略定义的其它各种消息
        public static final int BIND_APPLICATION        = 110;
        public static final int EXIT_APPLICATION        = 111;

        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BIND_APPLICATION:
                    AppBindData data = (AppBindData)msg.obj;
                    handleBindApplication(data);
                    break;
                    
                case EXIT_APPLICATION:
                    if (mInitialApplication != null) {
                        mInitialApplication.onTerminate();
                    }
                    Looper.myLooper().quit();
                    break;
        }
        
         Object obj = msg.obj;
            if (obj instanceof SomeArgs) {
                ((SomeArgs) obj).recycle(); //释放资源
            }
    }
复制代码

ActivityThread#handleBindApplication()

mInstrumentation实例化

通过mInstrumentation调用Application.onCreate()

private void handleBindApplication(AppBindData data) {

        if (ii != null) {
            mInstrumentation = (Instrumentation)
                    cl.loadClass(data.instrumentationName.getClassName()).newInstance();
                    
            mInstrumentation.init(this, instrContext, appContext, component,
                    data.instrumentationWatcher, data.instrumentationUiAutomationConnection);
        } else {
            mInstrumentation = new Instrumentation();
        }

 mInstrumentation.onCreate(data.instrumentationArgs);
 mInstrumentation.callApplicationOnCreate(app);

    }
复制代码

Instrumentation#callApplicationOnCreate()

这里就回调到用户自定义的Application了(如果自定义了的话)

   public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }
复制代码

总结

  • ActivityThread是应用程序的主入口,在Looper.loop之前实现Application的初始化,attach(false)

  • 通过Binder机制获得AMS的实例,跨进度调度AMS.attachApplication(thread),thread是一个ApplicationThread对象,ApplicationThread实现了IpplicationThread

  • 通过Binder机制,thread.bindApplication(xxx),回调到ApplicationThread.bindApplication()中,此时会通过mH发出一个BIND_APPLICATION的消息。

  • mH是一个H对象,H收到这个BIND_APPLICATION消息,执行handleBindApplication(),里面会对mInstrumentation进行初始化

  • mInstrumentation#callApplicationOnCreate()最终会调用Application的onCreate()。

也就是说Application的启动过程是由系统通过Binder机制控制的。

转载于:https://juejin.im/post/5b655df9e51d45194b1937c1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值