android.app.Apolication
frameworks/base/core/java/android/app/Application.java
/**
* Base class for maintaining global application state. You can provide your own
* implementation by creating a subclass and specifying the fully-qualified name
* of this subclass as the <code>"android:name"</code> attribute in your
* AndroidManifest.xml's <code><application></code> tag.
* The Application class, or your subclass of the Application class, is instantiated before any
* other class when the process for your application/package is created.
*/
//Appliation是提供对组件处理的入口如low memory等
public class Application extends ContextWrapper implements ComponentCallbacks2 {// memory manager lower
private ArrayList<ComponentCallbacks> mComponentCallbacks =
new ArrayList<ComponentCallbacks>();
private ArrayList<ActivityLifecycleCallbacks> mActivityLifecycleCallbacks =
new ArrayList<ActivityLifecycleCallbacks>();
private ArrayList<OnProvideAssistDataListener> mAssistCallbacks = null;
//以mComponentCallbacks为例,register/unregister callback
public void registerComponentCallbacks(ComponentCallbacks callback) {
synchronized (mComponentCallbacks) {
mComponentCallbacks.add(callback);
}
}
public void unregisterComponentCallbacks(ComponentCallbacks callback) {
synchronized (mComponentCallbacks) {
mComponentCallbacks.remove(callback);
}
}
//ArrayList -> Array
private Object[] collectComponentCallbacks() {
Object[] callbacks = null;
synchronized (mComponentCallbacks) {
if (mComponentCallbacks.size() > 0) {
callbacks = mComponentCallbacks.toArray();
}
}
return callbacks;
}
//当low memory发生时,调用register的callback
@CallSuper
public void onLowMemory() {
Object[] callbacks = collectComponentCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ComponentCallbacks)callbacks[i]).onLowMemory();
}
}
}
}
android.app.LoadedApk
frameworks/base/core/java/android/app/LoadedApk.java
//Local state maintained about a currently loaded .apk.
//apk文件在内存中的展现
public final class LoadedApk {
static final String TAG = "LoadedApk";
static final boolean DEBUG = false;
private final ActivityThread mActivityThread;
final String mPackageName;
private ApplicationInfo mApplicationInfo;
//文件,数据,库等的路径
private String mAppDir;
private String mResDir;
private String[] mOverlayDirs;
private String mDataDir;
private String mLibDir;
private File mDataDirFile;
private File mDeviceProtectedDataDirFile;
private File mCredentialProtectedDataDirFile;
private final ClassLoader mBaseClassLoader;
}
ActivityThread attached的过程
ActivityThread thread = new ActivityThread();
thread.attach(false);
1] ApplicationThread mAppThread = new ApplicationThread();
引入ApplicationThread 类
/**
* System private API for communicating with the application. This is given to
* the activity manager by an application when it starts up, for the activity
* manager to tell the application about things it needs to do.
*/
private class ApplicationThread extends IApplicationThread.Stub {// server端
如接口实现scheduleCreateService
public final void scheduleCreateService(IBinder token,
ServiceInfo info, CompatibilityInfo compatInfo, int processState) {
updateProcessState(processState, false);
CreateServiceData s = new CreateServiceData();
s.token = token;
s.info = info;
s.compatInfo = compatInfo;
sendMessage(H.CREATE_SERVICE, s);
}//由ActivityThread的HandleMessage进行处理
2. call into ActivityManagerService.attachApplication
private void attach(boolean system) {
final IActivityManager mgr = ActivityManager.getService();
try {
mgr.attachApplication(mAppThread);
}
}
public final void attachApplication(IApplicationThread thread) {//把IApplicationThread 传入server
synchronized (this) {
int callingPid = Binder.getCallingPid();
attachApplicationLocked(thread, callingPid);
}
}
private final boolean attachApplicationLocked(IApplicationThread thread, int pid) {
// Find the application record that is being attached...
ProcessRecord app;
app = mPidsSelfLocked.get(pid);
app.makeActive(thread, mProcessStats);
app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
//ApplicationInfo的信息来着ProcessRecord
ApplicationInfo appInfo = app.instr != null ? app.instr.mTargetInfo : app.info;
app.compat = compatibilityInfoForPackageLocked(appInfo);
//bind Application
thread.bindApplication(processName, ...);
}
3. 又通过IApplicationThread调回ActivityThread
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;
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);//HandleMessage处理
}
HandleMessage:
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
private void handleBindApplication(AppBindData data) {
//获得LoadApk
data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
// Instrumentation info affects the class loader, so load it before
// setting up the app context.
final InstrumentationInfo ii;
if (data.instrumentationName != null) {
try {
ii = new ApplicationPackageManager(null, getPackageManager())
.getInstrumentationInfo(data.instrumentationName, 0);
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find instrumentation info for: " + data.instrumentationName);
}
mInstrumentationPackageName = ii.packageName;
mInstrumentationAppDir = ii.sourceDir;
mInstrumentationSplitAppDirs = ii.splitSourceDirs;
mInstrumentationLibDir = getInstrumentationLibrary(data.appInfo, ii);
mInstrumentedAppDir = data.info.getAppDir();
mInstrumentedSplitAppDirs = data.info.getSplitAppDirs();
mInstrumentedLibDir = data.info.getLibDir();
}
// create Application context
final ContextImpl appContext = ContextImpl.createAppContext(this, data.info);
updateLocaleListFromAppContext(appContext, mResourcesManager.getConfiguration().getLocales());
mInstrumentation = new Instrumentation();
Application app;
try {
// If the app is being launched for full backup or restore, bring it up in
// a restricted environment with the base application class.
app = data.info.makeApplication(data.restrictedBackupMode, null);
mInitialApplication = app;
}
}
public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai,
CompatibilityInfo compatInfo) {
return getPackageInfo(ai, compatInfo, null, false, true, false);
}
3.1 怎样获得LoadedApk
private LoadedApk getPackageInfo(ApplicationInfo aInfo, CompatibilityInfo compatInfo,
ClassLoader baseLoader, boolean securityViolation, boolean includeCode,
boolean registerPackage) {
final boolean differentUser = (UserHandle.myUserId() != UserHandle.getUserId(aInfo.uid));
synchronized (mResourcesManager) {
WeakReference<LoadedApk> ref;
if (differentUser) {
// Caching not supported across users
ref = null;
} else if (includeCode) {
ref = mPackages.get(aInfo.packageName);
} else {
ref = mResourcePackages.get(aInfo.packageName);
}
LoadedApk packageInfo = ref != null ? ref.get() : null;
if (packageInfo == null){
packageInfo = new LoadedApk();//创建LoadedApk对象
}
return packageInfo;
}
3.2 创建Application:based on class load, class name and appContext
public Application makeApplication(boolean forceDefaultAppClass, Instrumentation instrumentation) {
String appClass = mApplicationInfo.className;
Application app = null;
try {
//create Application
java.lang.ClassLoader cl = getClassLoader();
ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);
app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);
appContext.setOuterContext(app);
}
mActivityThread.mAllApplications.add(app);
mApplication = app;
}
3.2.1 Instrumentation.newApplication
frameworks/base/core/java/android/app/Instrumentation.java
public Application newApplication(ClassLoader cl, String className, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
return newApplication(cl.loadClass(className), context);
}
static public Application newApplication(Class<?> clazz, Context context)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
Application app = (Application)clazz.newInstance();
app.attach(context);
return app;
}
3.2.2 attach application context
/* package */ final void attach(Context context) {
attachBaseContext(context);
mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
frameworks/base/core/java/android/content/ContextWrapper.java
protected void attachBaseContext(Context base) {
mBase = base;
}