App启动(一)Application的创建
大家都知道Java程序的入口是 main
方法,但在Android中我们只知道App启动从Application
开始,而Android是基于Java的,本身也是从main
方法开始的,而这个 main
方法是在ActivityThread
类的。下面我们就看下ActivityThread
的main
方法是如何工作的。
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
类有一个H
(Handler
的子类)类型的变量mh
,并进行了实例化,而后面则是调用Looper.loop()
开启了消息循环。
也就是说main
方法所在的线程就是我们常说的主线程,我们继续看main
方法,可以看到创建ActivityThread
的对象后,调用了attach
方法,在这个方法里进行了Application
、Activity
的相关创建。
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是运行在系统进程,主要完成管理应用进程的生命周期以及进程的Activity
,Service
,Broadcast
和Provider
等。
我们继续回到attach
方法,这里调用了一行代码mgr.attachApplication(mAppThread);
,通过AMS的attachApplication
方法将mAppThread
对象关联到了AMS。
而AMS通过调用mAppThread
的相关方法进行Application
的创建、生命周期的管理和Activity
的创建、生命周期管理等,既然bindApplication对象如此重要,那么我们来看下它到底是什么
3.mAppThread
是什么?
mAppThread
是ActivityThread
的一个ApplicationThread
类型的变量,而ApplicationThread
是ActivityThread
的一个内部类,大概代码结构如下:
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通过远程调用ApplicationThread
的bindApplication
方法进行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
类进行处理
我们知道Handler
在handleMessage
方法里进行消息处理
public void handleMessage(Message msg) { switch (msg.what) { ... case BIND_APPLICATION: AppBindData data = (AppBindData)msg.obj; handleBindApplication(data); break; ... }}
消息经过Hander处理后交给了ActivityThread
的handleBindApplication
方法处理
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.info
为LoadedApk
类型的对象,我们去这个类看它的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
去创建对象,我们继续看Instrumentation
的 newApplication
方法
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
。这个方法里调用了Application
的attachBaseContext
方法,这是我们应用端可以使用的最早的生命周期方法
final void attach(Context context) { //注意这个方法是一个可以比onCreate更早被调用的方法 attachBaseContext(context); mLoadedApk = ContextImpl.getImpl(context).mPackageInf;}
我们继续回到handleBindApplication
方法里,通过LoadedApp
的makeApplication
创建Application
实例后会调用mInstrumentation.callApplicationOnCreate(app)
这行代码执行Application
的onCreate
生命周期
public void callApplicationOnCreate(Application app) { app.onCreate();}
可以看到只是简单的调用了Application
的onCreate
方法,这是我们与Application
打交道最多的方法。
至此Application
对象已经创建出来了,并且我们已经走到了onCreate生命周期对象。Application的创建就分析到这里了。
方法调用流程图
更多相关文章
- Android栗子の图片验证码生成实例代码
- 安装Android studio出现'tools.jar' seems to be not in Android
- Android 屏幕旋转后防止重新执行onCreate的方法。
- 【Android】‘activity supporting action_view is not set as b
- Android中完全退出程序的四种方法
- 【Android】刮刮卡实例
- [Android]瀑布流实例android_waterfall源码分析