App启动(一)Application的创建

9 篇文章 0 订阅
7 篇文章 0 订阅

大家都知道Java程序的入口是 main 方法,但在Android中我们只知道App启动从Application开始,而Android是基于Java的,本身也是从main方法开始的,而这个 main方法是在ActivityThread类的。下面我们就看下ActivityThreadmain方法是如何工作的。

1. ActivityThread #main

public static void main(String[] args){
    ...
    //初始化Looper
    Looper.prepareMainLooper(); 
    ...
    //实例化一个ActivityThread
    ActivityThread thread = new ActivityThread();
    //这个方法最后就是为了发送出创建Application的消息
    thread.attach(false);
    ... 
    Looper.loop();
    //主线程进入无限循环状态,等待接收消息
}


很明显这里使用了Handler机制,先初始化Looper,然后实例化一个ActivityThread对象,而ActivityThread类有一个HHandler的子类)类型的变量mh,并进行了实例化,而后面则是调用Looper.loop()开启了消息循环。

也就是说main方法所在的线程就是我们常说的主线程,我们继续看main方法,可以看到创建ActivityThread的对象后,调用了attach方法,在这个方法里进行了ApplicationActivity的相关创建。

2. ActivityThread #attach

public void attach(boolean system){
    ...
    //获得IActivityManager实例,他是一个ActivityManagerProxy的示例
     final IActivityManager mgr = ActivityManager.getService();
    try {
        //这里是关键。mAppThread是一个ApplicationThread实例,具体的在下面说
        mgr.attachApplication(mAppThread);
    } catch (RemoteException ex) {
        throw ex.rethrowFromSystemServer();
    }
    ...
}

首先我们拿到了一个IActivityManager的实例,它是通过ActivityManager.getService()获取到的

我们看下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;
        }
};

可以看到IActivityManager的实例是一个ActivityManagerService通过Binder机制得到的远程对象,而ActivityManagerService即AMS是运行在系统进程,主要完成管理应用进程的生命周期以及进程的ActivityServiceBroadcastProvider等。

我们继续回到attach方法,这里调用了一行代码mgr.attachApplication(mAppThread);,通过AMS的attachApplication方法将mAppThread对象关联到了AMS。

而AMS通过调用mAppThread的相关方法进行Application的创建、生命周期的管理和Activity的创建、生命周期管理等,既然bindApplication对象如此重要,那么我们来看下它到底是什么

3.mAppThread是什么?

mAppThreadActivityThread 的一个ApplicationThread 类型的变量,而ApplicationThreadActivityThread 的一个内部类,大概代码结构如下:

public final class ActivityThread {
	...
	final ApplicationThread mAppThread = new ApplicationThread();
	...
	private class ApplicationThread extends IApplicationThread.Stub {
        ...
    }
	public static void main(String[] args){
		...
	}
}

显然ApplicationThread是一个BInder对象,可以通过Binder机制远程访问,这也就是为什么我们要将它传递给AMS的原因,AMS可以通过Binder机制调用它的的相关方法进行上面所说的Application的创建、声明周期的管理等。

首先AMS通过远程调用ApplicationThreadbindApplication方法进行Application对象的创建

4.ApplicationThread#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 enableBinderTracking, boolean trackAllocation,
    boolean isRestrictedBackupMode, boolean persistent, Configuration config,
    CompatibilityInfo compatInfo, Map services, Bundle coreSettings,
    String buildSerial) {
    
    AppBindData data = new AppBindData();
    data.processName = processName;
    data.appInfo = appInfo;
    data.providers = providers;
    data.instrumentationName = instrumentationName;
    ...
    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;
    if (async) {
        msg.setAsynchronous(true);
    }
    mH.sendMessage(msg);
}

可以看到bindApplication方法通过Handler机制发送了H.BIND_APPLICATION消息将实现交给了H类进行处理

我们知道HandlerhandleMessage方法里进行消息处理

public void handleMessage(Message msg) {
    switch (msg.what) {
            ...
            case BIND_APPLICATION:
                AppBindData data = (AppBindData)msg.obj;
                handleBindApplication(data);
                break;
            ...
    }
}

消息经过Hander处理后交给了ActivityThreadhandleBindApplication方法处理

5.ActivityThread #handleBindApplication

private void handleBindApplication(AppBindData data) {
    ...
    mInstrumentation = (Instrumentation)
        cl.loadClass(data.instrumentationName.getClassName())
        .newInstance();
    //通过反射初始化一个Instrumentation仪表。
    ...
    Application app;
    try {
         //通过LoadedApp的makeApplication创建Application实例
        app = data.info.makeApplication(data.restrictedBackupMode, null);
        mInitialApplication = app;
   
        ...
        //让Instrumentation仪表调用Application的onCreate()方法
        mInstrumentation.callApplicationOnCreate(app);
        ...
    }
    ...
}

通过上面源码我们可以看到这里使用data.info.makeApplication方法创建了Application对象

data.infoLoadedApk类型的对象,我们去这个类看它的makeApplication 方法

public Application makeApplication(boolean forceDefaultAppClass,
    Instrumentation instrumentation) {
    ...
    String appClass = mApplicationInfo.className;
    //获取Application的类名。明显是要用反射了。
    ...
    ContextImpl appContext = ContextImpl.createAppContext(mActivityThread
        , this);
    //留意下Context
    app = mActivityThread.mInstrumentation
        .newApplication( cl, appClass, appContext);
    //通过Instrumentation仪表创建Application
    ...
}

方法里获取了 Application 的类名,然后交给了 Instrumentation去创建对象,我们继续看InstrumentationnewApplication方法

static public Application newApplication(Class<?> clazz
    , Context context) throws InstantiationException
    , IllegalAccessException
    , ClassNotFoundException {
    //反射创建,简单粗暴
        Application app = (Application)clazz.newInstance();
        //关注下这里,Application被创建后第一个调用的方法。
        //目的是为了绑定Context。
        app.attach(context);
        return app;
}

Instrumentation直接用反射创建了Application 对象,然后调用了app.attach(context)方法绑定Context。这个方法里调用了ApplicationattachBaseContext方法,这是我们应用端可以使用的最早的生命周期方法

final void attach(Context context) {
   //注意这个方法是一个可以比onCreate更早被调用的方法
   attachBaseContext(context);
   mLoadedApk = ContextImpl.getImpl(context).mPackageInf;
}

我们继续回到handleBindApplication方法里,通过LoadedAppmakeApplication创建Application实例后会调用mInstrumentation.callApplicationOnCreate(app)这行代码执行ApplicationonCreate生命周期

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

可以看到只是简单的调用了ApplicationonCreate方法,这是我们与Application打交道最多的方法。

至此Application对象已经创建出来了,并且我们已经走到了onCreate生命周期对象。Application的创建就分析到这里了。

方法调用流程图

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值