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

 Application app  = data.info.makeApplication(data.restrictedBackupMode, null);
 mInstrumentation.onCreate(data.instrumentationArgs);
 mInstrumentation.callApplicationOnCreate(app);

    }

LoadApk#makeApplication()

实例化Application,回调Application.onAttach(contextImpl),绑定contextImpl对象。

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        if (mApplication != null) {
            return mApplication;
        }
        Application app = null;
        String appClass = mApplicationInfo.className;

            java.lang.ClassLoader cl = getClassLoader();
            ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
        return app;
    }

Instrumentation#newApplication()

public Application newApplication(ClassLoader cl, String className, Context context)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
           //通过类加载方式实例化类对象
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
         //application.attach,绑定contextImpl对象
        app.attach(context);
        return app;
    }

AppComponentFactory#instantiateApplication

public Application instantiateApplication(ClassLoader cl, String className)
            throws InstantiationException, IllegalAccessException, ClassNotFoundException {
        return (Application) cl.loadClass(className).newInstance();
    }

Instrumentation#callApplicationOnCreate()

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

   public void callApplicationOnCreate(Application app) {
        app.onCreate();
    }

总结

  • ActivityThread是应用程序的主入口,通过attach(false) 初始化Application.

  • 通过ServiceManager查询获得AMS的实例,跨进程调度AMS.attachApplication(thread),thread是一个ApplicationThread对象,即客户端的binder对象,ApplicationThread继承自IApplicationThread.Stub,

  • AMS判断处理后,回调thread.bindApplication(xxx) -> ApplicationThread.bindApplication()中,又回到了App进程,通过mH发出一个BIND_APPLICATION的消息。

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

  • 通过类加载方式实例化Application对象,执行attach,绑定ContextImpl对象;执行onCreate()。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值