谈谈你对Application的理解
1.它的作用是什么
- 保存应用的全局变量
- 初始化第三方库
2.它的类继承关系以及生命周期
public class Application extends ContextWrapper implements ComponentCallbacks2 {
}
public class ContextWrapper extends Context {
//Application里面实质用的是这个mBase
Context mBase;
public ContextWrapper(Context base) {
mBase = base;
}
/**
* Set the base context for this ContextWrapper. All calls will then be
* delegated to the base context. Throws
* IllegalStateException if a base context has already been set.
*
* @param base The new base context for this wrapper.
*/
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
}
3.它的初始化原理
ActivityThread的main里面调用attach,向AMS打报告,报告自己appthread准备就绪
private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
try {
//这里有ipc
mgr.attachapplication(mappthread);
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
到AMS中去找
@Override
public final void attachApplication(IApplicationThread thread) {
synchronized (this) {
int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
attachApplicationLocked(thread, callingPid);
Binder.restoreCallingIdentity(origId);
}
}
//这里ipc
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);
到APP ActivityThread去找,之后经过Handler发送消息回调中:
private void handleBindApplication(AppBindData data) {
//获取LoadedApk信息
final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo,
appContext.getClassLoader(), false, true, false);
final ContextImpl instrContext = ContextImpl.createAppContext(this, pi);
try {
final ClassLoader cl = instrContext.getClassLoader();
mInstrumentation = (Instrumentation)
cl.loadClass(data.instrumentationName.getClassName()).newInstance();
} catch (Exception e) {
throw new RuntimeException(
"Unable to instantiate instrumentation "
+ data.instrumentationName + ": " + e.toString(), e);
}
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInstrumentation.callApplicationOnCreate(app);
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
*/ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
protected void attachBaseContext(Context base) {
if (mBase != null) {
throw new IllegalStateException("Base context already set");
}
mBase = base;
}
这里需要注意一点,Application的context是在attachBaseContext回调之后才有的,也就是如果我们在Application的构造函数中去使用context 是会抛异常的,如下
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference