Android四大组件系列11 Application创建流程

一 概述

system_server 进程和 app 进程都运行着一个或多个 app,每个 app 都会有一个对应的 Application 对象(该对象跟 LoadedApk 一一对应)。下面分别分析这两种进程创建 Application 的过程:

  • system_server 进程
  • app 进程

二 system_server进程

2.1 SystemServer.run

frameworks/base/services/java/com/android/server/SystemServer.java

public final class SystemServer {
    private static final String TAG = "SystemServer";
    ......
    public static void main(String[] args) {
        new SystemServer().run();
    }
    ......
    private void run() {
        try {
            ......            
            createSystemContext();
            ......
        } finally {
            ......
        }        
        ......
    }
}


private void createSystemContext() {
      ActivityThread activityThread = ActivityThread.systemMain();
      mSystemContext = activityThread.getSystemContext();
      mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);

      final Context systemUiContext =
            activityThread.getSystemUiContext();
      systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
}

2.2 ActivityThread.systemMain

frameworks/base/core/java/android/app/ActivityThread.java

public static ActivityThread systemMain() {
        ......
        ActivityThread thread = new ActivityThread();
        thread.attach(true, 0);
        return thread;
}

public final class ActivityThread extends ClientTransactionHandler {
    //创建ApplicationThread对象
    final ApplicationThread mAppThread = new ApplicationThread();
    final Looper mLooper = Looper.myLooper();
    final H mH = new H();
    //当前进程中首次初始化的app对象
    Application mInitialApplication;
    final ArrayList<Application> mAllApplications
            = new ArrayList<Application>();
    //标记当前进程是否为system进程
    boolean mSystemThread = false;
    //记录system进程的ContextImpl对象
    private ContextImpl mSystemContext;
    private ContextImpl mSystemUiContext;

    final ArrayMap<String, WeakReference<LoadedApk>> mPackages = 
            new ArrayMap<>();
    static volatile Handler sMainThreadHandler;//set once in main()
    private static volatile ActivityThread sCurrentActivityThread;

    ActivityThread() {
        mResourcesManager = ResourcesManager.getInstance();
    }
}

其中 mInitialApplication 的赋值过程分两种场景:

  • system_server 进程是由 ActivityThread.attach() 过程赋值
  • 普通 app 进程是由是由 ActivityThread.handleBindApplication() 过程赋值,这是进程刚创建后 attach 到 system_server 后, 便会 binder call 到 app 进程来执行该方法

ActivityThread.currentApplication 返回的便是 mInitialApplication 对象。创建完 ActivityThread 对象,接下来执行 attach() 操作。

2.3 ActivityThread.attach

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system; //设置mSystemThread为true
    if (!system) {
        ......
    } else { //system进程才执行该流程
        try {
           //创建Instrumentation
           mInstrumentation = new Instrumentation();
           mInstrumentation.basicInit(this);
           ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
           mInitialApplication =
           context.mPackageInfo.makeApplication(true, null);
           mInitialApplication.onCreate();
        } catch (Exception e) {
                ......
        }
        ......
    }
}

2.3.1 Application.onCreate

public void onCreate() {//方法为空, 一般由其子类实现该方法
}

2.4 ContextImpl.createAppContext

static ContextImpl createAppContext(ActivityThread mainThread,
        LoadedApk packageInfo) {
        return createAppContext(mainThread, packageInfo, null);
}


static ContextImpl createAppContext(ActivityThread mainThread, 
      LoadedApk packageInfo, String opPackageName) {
        if (packageInfo == null) 
        throw new IllegalArgumentException("packageInfo");
        ContextImpl context = new ContextImpl(null, mainThread, packageInfo,
        null, null, null, 0, null, opPackageName);
        context.setResources(packageInfo.getResources());
        return context;
}

创建 ContextImpl 对象有多种方法,常见的有:

createSystemContext(ActivityThread mainThread)
createAppContext(ActivityThread mainThread, LoadedApk packageInfo)
createApplicationContext(ApplicationInfo application, int flags)
createPackageContext(String packageName, int flags)
createSystemUiContext(ContextImpl systemContext)
createActivityContext(ActivityThread mainThread, ......)

此处,packageInfo 是 getSystemContext().mPackageInfo,getSystemContext() 获取的 ContextImpl 对象, 其成员变量 mPackageInfo 便是 LoadedApk 对象。所以先来看看 getSystemContext() 过程。

2.4.1 ActivityThread.getSystemContext

public ContextImpl getSystemContext() {
    synchronized (this) {
        if (mSystemContext == null) {
            mSystemContext = ContextImpl.createSystemContext(this);
        }
        return mSystemContext;
    }
}

单例模式创建 mSystemContext 对象

2.4.2 ContextImpl.createSystemContext

static ContextImpl createSystemContext(ActivityThread mainThread) {
        LoadedApk packageInfo = new LoadedApk(mainThread);
        ContextImpl context = new ContextImpl(null, mainThread,
        packageInfo, null, null, null, 0, null, null);
        ......
        return context;
}

2.4.3 LoadedApk初始化

public final class LoadedApk {
    private final ActivityThread mActivityThread;
    private ApplicationInfo mApplicationInfo;
    private Application mApplication;
    final String mPackageName;
    private final ClassLoader mBaseClassLoader;
    private ClassLoader mClassLoader;

    LoadedApk(ActivityThread activityThread) {
        mActivityThread = activityThread;//ActivityThread对象
        mApplicationInfo = new ApplicationInfo();//创建ApplicationInfo对象
        mApplicationInfo.packageName = "android";
        mPackageName = "android";//默认包名为"android"
        ......
        mBaseClassLoader = null;
        mClassLoader = mAppComponentFactory.instantiateClassLoader(
        mDefaultClassLoader, new ApplicationInfo(mApplicationInfo));
        ......
    }
}

只有一个参数的 LoadedApk 构造方法只有 createSystemContext() 过程才会创建, 其中 LoadedApk 初始化过程会创建 ApplicationInfo 对象,且包名为 “android”。 创建完 LoadedApk 对象,接下来创建 ContextImpl 对象。

2.4.4 ContextImpl初始化

class ContextImpl extends Context {
    final ActivityThread mMainThread;
    final LoadedApk mPackageInfo;
    private final IBinder mActivityToken;
    private final String mBasePackageName;
    private Context mOuterContext;
    //缓存Binder服务
    final Object[] mServiceCache = 
    SystemServiceRegistry.createServiceCache();

    private ContextImpl(ContextImpl container, ActivityThread mainThread,
    LoadedApk packageInfo, IBinder activityToken, ......) {
        mOuterContext = this; //ContextImpl对象
        mMainThread = mainThread; // ActivityThread赋值
        mPackageInfo = packageInfo; // LoadedApk赋值
        mBasePackageName = packageInfo.mPackageName; //mBasePackageName等于“android”
        ......
    }
}

首次执行 getSystemContext,会创建 LoadedApk 和 contextImpl 对象,接下来利用刚创建的 LoadedApk 对象来创建新的 ContextImpl 对象。

2.5 LoadedApk.makeApplication

public Application makeApplication(boolean forceDefaultAppClass,
            Instrumentation instrumentation) {
        //保证一个LoadedApk对象只创建一个对应的Application对象
        if (mApplication != null) {
            return mApplication;
        }
        ......
        Application app = null;
        String appClass = mApplicationInfo.className;
        if (forceDefaultAppClass || (appClass == null)) {
        //system_server进程, 则进入该分支
            appClass = "android.app.Application";//设置应用类名
        }
        try {
            java.lang.ClassLoader cl = getClassLoader();
            if (!mPackageName.equals("android")) {
                Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        "initializeJavaContextClassLoader");
                initializeJavaContextClassLoader();
                Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
            }
            //创建ContextImpl对象
            ContextImpl appContext = 
            ContextImpl.createAppContext(mActivityThread, this);
      //创建Application对象, 并将appContext attach到新创建的Application
            app = mActivityThread.mInstrumentation.newApplication(
                    cl, appClass, appContext);
            appContext.setOuterContext(app);
        } catch (Exception e) {
            ......
        }
        mActivityThread.mAllApplications.add(app);
        mApplication = app;//将刚创建的app赋值给mApplication

        if (instrumentation != null) {
            try {
                //调用application的OnCreate方法
                instrumentation.callApplicationOnCreate(app);
            } catch (Exception e) {
                ......
            }
        }
        ......
        return app;
}

2.6 LoadedApk.initializeJavaContextClassLoader

private void initializeJavaContextClassLoader() {
        IPackageManager pm = ActivityThread.getPackageManager();
        android.content.pm.PackageInfo pi;
        try {
            pi = pm.getPackageInfo(mPackageName, 
            PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
                    UserHandle.myUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
        if (pi == null) {
            ......
        }
        boolean sharedUserIdSet = (pi.sharedUserId != null);
        boolean processNameNotDefault =
            (pi.applicationInfo != null &&
             !mPackageName.equals(pi.applicationInfo.processName));
        boolean sharable = 
              (sharedUserIdSet || processNameNotDefault);
        ClassLoader contextClassLoader =
            (sharable)
            ? new WarningContextClassLoader()
            : mClassLoader;
    Thread.currentThread().setContextClassLoader(contextClassLoader);
}

2.7 Instrumentation.newApplication

public Application newApplication(ClassLoader cl, String className,
      Context context) throws InstantiationException, ...... {
        Application app = getFactory(context.getPackageName())
                .instantiateApplication(cl, className);
        app.attach(context);
        return app;
}


private AppComponentFactory getFactory(String pkg) {
        if (pkg == null) {
    Log.e(TAG, "No pkg specified, disabling AppComponentFactory");
            return AppComponentFactory.DEFAULT;
        }
        if (mThread == null) {
           ......
            return AppComponentFactory.DEFAULT;
        }
        LoadedApk apk = mThread.peekPackageInfo(pkg, true);
        // This is in the case of starting up "android".
    if (apk == null) apk = mThread.getSystemContext().mPackageInfo;
        return apk.getAppFactory();
}

AppComponentFactory.java
public @NonNull Application instantiateApplication(ClassLoader cl,
            @NonNull String className)
            throws InstantiationException, ...... {
        return (Application) cl.loadClass(className).newInstance();
}

2.8 Application.attach

final void attach(Context context) {
     attachBaseContext(context);
     mLoadedApk = ContextImpl.getImpl(context).mPackageInfo;
}
    
Application父类ContextWraper.java
protected void attachBaseContext(Context base) {
    if (mBase != null) {
        throw new IllegalStateException("Base context already set");
    }
    mBase = base;
}
  • 将新创建的 ContextImpl 对象保存到 Application 父类成员变量 mBase
  • 将新创建的 LoadedApk 对象保存到 Application 的父员变量 mLoadedApk

三 App进程

3.1 ActivityThread.main

public static void main(String[] args) {
    Looper.prepareMainLooper();
    ......
    ActivityThread thread = new ActivityThread();
    thread.attach(false, startSeq);
    ......
    Looper.loop();
}

这是运行在 app 进程,当进程由 zygote fork 后执行 ActivityThread 的 main 方法,注意 attach 函数的参数,这里为 false。

3.2 ActivityThread.attach

private void attach(boolean system, long startSeq) {
    sCurrentActivityThread = this;
    mSystemThread = system; //设置mSystemThread为true
    if (!system) {//app进程
        ......
        final IActivityManager mgr = ActivityManager.getService();
        try {
            mgr.attachApplication(mAppThread, startSeq);
        } catch (RemoteException ex) {
            throw ex.rethrowFromSystemServer();
        }
        ......
    } else { //system进程才执行该流程
        ......
    }
}

经过 Binder 调用,进入 system_server 进程,执行 attachApplication。

3.3 AMS.attachApplication

public final void attachApplication(IApplicationThread thread,
    long startSeq) {
      if (thread == null) {
        throw new SecurityException("Invalid application interface");
      }
      synchronized (this) {
          int callingPid = Binder.getCallingPid();
          final int callingUid = Binder.getCallingUid();
          final long origId = Binder.clearCallingIdentity();
    attachApplicationLocked(thread, callingPid, callingUid, startSeq);
          Binder.restoreCallingIdentity(origId);
      }
}


private boolean attachApplicationLocked(IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        ProcessRecord app;
        ......
        try {
            ......
         if (app.isolatedEntryPoint != null) {
                ......
         } else if (instr2 != null) {
            // 绑定App进程
          thread.bindApplication(processName, appInfo, providers,
              instr2.mClass,
              profilerInfo, instr2.mArguments,
              instr2.mWatcher,
              instr2.mUiAutomationConnection, testMode,
              mBinderTransactionTrackingEnabled, enableTrackAllocation,
              isRestrictedBackupMode || !normalMode, app.isPersistent(),
    new Configuration(app.getWindowProcessController().getConfiguration()),
              app.compat, getCommonServicesLocked(app.isolated),
              mCoreSettingsObserver.getCoreSettingsLocked(),
              buildSerial, autofillOptions, contentCaptureOptions);
         } else {
                ......
         }
            ......
        } catch (Exception e) {
           ......
           return false;
        }
        ......
        return true;
}

3.3 ActivityThread.bindApplication

public final void bindApplication(String processName, ......) {
       ......
// 封装App进程绑定数据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;
    data.autofillOptions = autofillOptions;
    data.contentCaptureOptions = contentCaptureOptions;
    sendMessage(H.BIND_APPLICATION, data);
}

3.4 ActivityThread.handleBindApplication

private void handleBindApplication(AppBindData data) {
    // 从AppBindData中取出InstrumentationInfo信息
    final InstrumentationInfo ii;
    if (data.instrumentationName != null) {
        ii = new ApplicationPackageManager(null, 
		getPackageManager()).getInstrumentationInfo(
		data.instrumentationName, 0);
        mInstrumentationPackageName = ii.packageName;
        mInstrumentationAppDir = ii.sourceDir;
        ......
    }
    //获取LoadedApk对象
    data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
    // 创建Context
    final ContextImpl appContext =
    ContextImpl.createAppContext(this, data.info);
 
	// InstrumentationInfo对象非空
	// 从InstrumentationInfo中取出各参数, 基于此创建和初始化Instrumentation
    if (ii != null) { 
        ApplicationInfo instrApp = getPackageManager()
	   .getApplicationInfo(ii.packageName, 0, UserHandle.myUserId());
        if (instrApp == null) {
            instrApp = new ApplicationInfo();
        }
        // 将InstrumentationInfo里的参数拷贝到ApplicationInfo对象
        ii.copyTo(instrApp);
        instrApp.initForUser(UserHandle.myUserId());
        final LoadedApk pi = getPackageInfo(instrApp, data.compatInfo, 
		        appContext.getClassLoader(), false, true, false);
 
        final ContextImpl instrContext =
        ContextImpl.createAppContext(this,
		        pi, appContext.getOpPackageName());
        final ClassLoader cl = instrContext.getClassLoader();
        mInstrumentation = (Instrumentation) cl
	    .loadClass(data.instrumentationName.getClassName()).newInstance();
        final ComponentName component = 
        new ComponentName(ii.packageName, ii.name);
        mInstrumentation.init(this, instrContext, ......);
    } else { // 初始化Instrumentation
        mInstrumentation = new Instrumentation();
        mInstrumentation.basicInit(this);
    }
 
    //创建Application对象
    Application app = 
    data.info.makeApplication(data.restrictedBackupMode, null);
    mInitialApplication = app;
     
    mInstrumentation.onCreate(data.instrumentationArgs);
    //调用Application.onCreate()方法.
    mInstrumentation.callApplicationOnCreate(app);
    ......
}

在 handleBindApplication() 的过程中,会创建 Application 并调用其 onCreate 方法

四 总结

system_server 进程

其 application 创建过程都创建对象有 ActivityThread,Instrumentation,ContextImpl,LoadedApk,Application。 流程图如下:
在这里插入图片描述
app 进程

其 application 创建过程都创建对象有 ActivityThread,ContextImpl,LoadedApk,Application。 流程图如下:
在这里插入图片描述
App 进程的 Application 创建过程,跟 system 进程的核心逻辑都差不多。只是 app 进程多了两次 binder 调用。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值