Android|App启动(一)Application的创建

大家都知道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()获取到的
【Android|App启动(一)Application的创建】我们看下ActivityManager.getService()相关的源码
public static IActivityManager getService() { return IActivityManagerSingleton.get(); }private static final Singleton IActivityManagerSingleton = new Singleton() { @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 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 = https://www.it610.com/article/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 = https://www.it610.com/article/(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的创建就分析到这里了。
方法调用流程图
Android|App启动(一)Application的创建
文章图片

    推荐阅读