理解Application的创建过程

前言

本文假设你已经了解了android的Binder机制,如果你还未了解相关知识,就没必要阅读本文了。

正文

一个进程可以运行多个app(mainfest中通过process:name可以指定),每个app都有一个Application对象,简单介绍下非系统进程创建Application的过程。
我们先看下ActivityMangerService(AMS)里创建进程的部分代码

Process.ProcessStartResult startResult = Process.start(entryPoint,
                    app.processName, uid, uid, gids, debugFlags, mountExternal,
                    app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
                    app.info.dataDir, entryPointArgs);
.....
this.mPidsSelfLocked.put(startResult.pid, app);
.....

返回的startResult里有个个成员变量pid,这个值是进程的id,AMS把这个值和ProcessRecord(描述进程的一个类)的一个实例以k-v的形式存了起来。Process.start调用了ActivityThread的main函数,这个函数主要作用是让当前线程变为Looper线程,当前线程也就是我们常说的UI线程或者主线程。

public static void main(String[] args){
   .....
   Looper.prepareMainLooper();
   ActivityThread thread = new ActivityThread();
   thread.attach(false);
   if (sMainThreadHandler == null) {
       sMainThreadHandler = thread.getHandler();
   }
   ...
   Looper.loop();
}

这里面还有一行重要的代码就是

thread.attach(false)l

我们看下这个attach方法

    private void attach(boolean system) {
        ...
        if (!system) {
            final IActivityManager mgr = ActivityManagerNative.getDefault();
            try {
                mgr.attachApplication(mAppThread);
            } catch (RemoteException ex) {
                throw ex.rethrowFromSystemServer();
            }
        } else {
           ...
        }
    }

如果你熟悉Binder机制的话,应该知道这里的mgr应该是ActivityManagerProxy(AMP)的一个实例。调用了mgr的attachApplicationd方法并把成员变量mAppThread当作参数传递了过去。我们看下mAppThread的定义

final ApplicationThread mAppThread = new ApplicationThread();

ApplicationThread 是ActivityThread的内部类,继承自ApplicationThreadNative,是个Binder对象。
调用mgr的attachApplication的方法实际上最终是调用AMS的attachApplication方法,我们看下这个方法在AMS中的定义。

 @Override
 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
     ...
    case ATTACH_APPLICATION_TRANSACTION: {
            data.enforceInterface(IActivityManager.descriptor);
            IApplicationThread app = ApplicationThreadNative.asInterface(
                    data.readStrongBinder());
            if (app != null) {
                attachApplication(app);
            }
            reply.writeNoException();
            return true;
        }
    ...
}
//onTransact 是ActivityMangrerNative中定义的,AMS是AMN的子类,我们看到 case ATTACH_APPLICATION_TRANSACTION: 这种情况下调用了attachApplicationf方法
@Override
public final void attachApplication(IApplicationThread thread) {
       synchronized (this) {
          int callingPid = Binder.getCallingPid();
         final long origId = Binder.clearCallingIdentity();
         attachApplicationLocked(thread, callingPid);
         ...
  }
}
private final attachApplicationLocked(IApplicationThread thread,int pid){
  ...
 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
                    profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
                    app.instrumentationUiAutomationConnection, testMode,
                    mBinderTransactionTrackingEnabled, enableTrackAllocation,
                    isRestrictedBackupMode || !normalMode, app.persistent,
                    new Configuration(mConfiguration), app.compat,
                    getCommonServicesLocked(app.isolated),
                    mCoreSettingsObserver.getCoreSettingsLocked());
  ...
}

AMS经过一系列处理,又通过RPC调用了ApplicationThread的bindApplication方法,我们看下这个方法的定义。

public final void bindApplication(String processName, ApplicationInfo appInfo,
         ...
        AppBindData data = new AppBindData();
        ...
        sendMessage(H.BIND_APPLICATION, data);
}

ApplicationThread组织参数后又丢给ActivityThread去处理,当ActivityThread收到这样一条消息时的处理方式如下

...
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;
...

我们看下 handleBindApplication(data)方法

private void handleBindApplication(AppBindData data) {
      ...
      data.info = getPackageInfoNoCheck(data.appInfo, data.compatInfo);
      ...
      Application app = data.info.makeApplication(data.restrictedBackupMode, null);
      mInitialApplication = app;
      ...
      mInstrumentation.callApplicationOnCreate(app);
}

data.info是个LoadedApk的实例,LoadedApk描述的是我们的apk文件。LoadApk调用newInstance方法创建了一个Application对象,然后通过

mInstrumentation.callApplicationOnCreate(app);

代码调用了Application对象的onCreate方法。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容