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机制控制的。