@act262
2017-05-24T14:25:59.000000Z
字数 4478
阅读 1149
AndroidSource
主要的类是ActivityThread,分为系统进程和我们的引用进程
系统进程:
SystemServer
public static void main(String[] args) {new SystemServer().run();}private void run() {//...// Initialize the system context.createSystemContext();// Create the system service manager.mSystemServiceManager = new SystemServiceManager(mSystemContext);LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);// Start services.startBootstrapServices();startCoreServices();startOtherServices();}
public static ActivityThread systemMain() {// The system process on low-memory devices do not get to use hardware// accelerated drawing, since this can add too much overhead to the// process.if (!ActivityManager.isHighEndGfx()) {HardwareRenderer.disable(true);} else {HardwareRenderer.enableForegroundTrimming();}ActivityThread thread = new ActivityThread();thread.attach(true);return thread;}
private void attach(boolean system){// ...// if systemtry {mInstrumentation = new Instrumentation();ContextImpl context = ContextImpl.createAppContext(this, getSystemContext().mPackageInfo);mInitialApplication = context.mPackageInfo.makeApplication(true, null);mInitialApplication.onCreate();} catch (Exception e) {throw new RuntimeException("Unable to instantiate Application():" + e.toString(), e);}}
简化为
LoadedApk packageInfo = new LoadedApk(this);ContextImpl context = ContextImpl.createAppContext(this, packageInfo);mInitialApplication = packageInfo.makeApplication(true,null);mInitialApplication.onCreate();
普通Application创建的起源:
在系统进程的控制下进入main函数,
ActivityThread.main() -> ActivityThread.attach(fasle) [handleBindApplication] -> LoadedApk.makeApplication() -> Instrumentation.newApplication()
Application类的调用链:
Application() -> Application.attach() -> Application.attachBaseContext() -> Application.onCreate()
ActivityThread的attach方法区分是否系统的进程
private void attach(boolean system) {}
LoadedApk类的方法
public Application makeApplication(boolean forceDefaultAppClass,Instrumentation instrumentation) {if (mApplication != null) {return mApplication;}Application app = null;String appClass = mApplicationInfo.className;if (forceDefaultAppClass || (appClass == null)) {appClass = "android.app.Application";}try {java.lang.ClassLoader cl = getClassLoader();if (!mPackageName.equals("android")) {initializeJavaContextClassLoader();}ContextImpl appContext = ContextImpl.createAppContext(mActivityThread, this);app = mActivityThread.mInstrumentation.newApplication(cl, appClass, appContext);appContext.setOuterContext(app);} catch (Exception e) {if (!mActivityThread.mInstrumentation.onException(app, e)) {throw new RuntimeException("Unable to instantiate application " + appClass+ ": " + e.toString(), e);}}mActivityThread.mAllApplications.add(app);mApplication = app;if (instrumentation != null) {try {instrumentation.callApplicationOnCreate(app);} catch (Exception e) {if (!instrumentation.onException(app, e)) {throw new RuntimeException("Unable to create application " + app.getClass().getName()+ ": " + e.toString(), e);}}}// Rewrite the R 'constants' for all library apks.SparseArray<String> packageIdentifiers = getAssets(mActivityThread).getAssignedPackageIdentifiers();final int N = packageIdentifiers.size();for (int i = 0; i < N; i++) {final int id = packageIdentifiers.keyAt(i);if (id == 0x01 || id == 0x7f) {continue;}rewriteRValues(getClassLoader(), packageIdentifiers.valueAt(i), id);}return app;}
Instrumentation
static public Application newApplication(Class<?> clazz, Context context)throws InstantiationException, IllegalAccessException,ClassNotFoundException {Application app = (Application)clazz.newInstance();app.attach(context);return app;}
Application类的attach方法,实际上主要是调用到了attachBaseContext方法
/* package */ final void attach(Context context) {attachBaseContext(context);mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;}
所以我们的关注点在attachBaseContext方法中,该方法在其父类ContextWrapper中定义的.
protected void attachBaseContext(Context base) {if (mBase != null) {throw new IllegalStateException("Base context already set");}mBase = base;}
子类重写的时候i.e.
protected void attachBaseContext(Context base) {super.attachBaseContext(base);MultiDex.install(this);}
常用作动态部署,热更新机制在这里操作 i.e.
@Overrideprotected void attachBaseContext(Context context) {// ...createRealApplication();// This is called from ActivityThread#handleBindApplication() -> LoadedApk#makeApplication().// Application#mApplication is changed right after this call, so we cannot do the monkey// patching here. So just forward this method to the real Application instance.super.attachBaseContext(context);if (realApplication != null) {try {Method attachBaseContext =ContextWrapper.class.getDeclaredMethod("attachBaseContext", Context.class);attachBaseContext.setAccessible(true);attachBaseContext.invoke(realApplication, context);} catch (Exception e) {throw new IllegalStateException(e);}}}