VirtualApp框架--- Application启动过程

一、VA 的Application为VApp,定义在io.virtualapp包中。VA重写了attachBaseContext()方法,在程序启动时会首先运行该方法,然后再调用VA的oncreate()方法。

二、VApp的attachBaseContext方法会去调用VirtualCore.getCore().startup(base)方法。

2.1. VirtualCore类定义在com.lody.virtual.client.core包中,getCore方法则是获取VirtualCore类的一个静态对象。接着调用该静态对象的startup方法。startup方法的部分源码如下

this.context = context;
            mainThread = ActivityThread.currentActivityThread();
            hostBindData = ActivityThreadCompat.getBoundApplication(mainThread);
            unHookPackageManager = context.getPackageManager();
            hostPkgInfo = unHookPackageManager.getPackageInfo(context.getPackageName(), PackageManager.GET_PROVIDERS);
            ProviderInfo[] hostProviders = hostPkgInfo.providers;
            if (hostProviders != null) {
                for (ProviderInfo info : hostProviders) {
                    hostProviderAuths.add(info.authority);

在上面代码中得出,首先获取当前的线程,然后获取这个线程的boundApplication对象,即AppBindData对象,在该对象中保存该线程的一些属性信息。然后调用context的getPackageManager方法获取了一个包管理器,然后通过传入当前包名获取当前的包信息,再然后就可以获取存储在报信息中的provider信息,最后将所有provider的authority属性保存到hostProviderAuths中。

2.2 接下来代码如下:

    // Host包名
            pkgName = context.getPackageName();
            // 主进程名
            mainProcessName = context.getApplicationInfo().processName;
            // 当前进程名
            processName = mainThread.getProcessName();
            if (processName.equals(mainProcessName)) {
                processType = ProcessType.Main;
            } else if (processName.endsWith(Constants.SERVER_PROCESS_NAME)) {
                processType = ProcessType.Server;
            } else if (LocalProcessManager.isAppProcess(processName)) {
                processType = ProcessType.VAppClient;
            } else {
                processType = ProcessType.CHILD;
            }
            PatchManager patchManager = PatchManager.getInstance();
            patchManager.injectAll();
            patchManager.checkEnv();
            RuntimeEnv.init();
            PatchManager.fixContext(context);
            isStartUp = true;

在上面的代码中首先获取当前包名,主进程名,当前进程名,然后判断当前进程的进程类型。进程类型分为四种,分别是服务端进程,插件客户端进程,主进程和子进程。前两张判断比较简单,直接比较当前进程名与主进程名是否相同可以判断是否为主进程;检查当前进程的名字是否以’:x’结尾可以判断是否为服务端进程。检查是否为插件客户端进程则需要调用LocalProcessManager类的isAppProcess方法。

2.3 接下来分析一下这个方法,这个方法的源码如下:

        public static boolean isAppProcess(String processName) {
        try {
            return getService().isAppProcess(processName);
        } catch (RemoteException e) {
            return RuntimeEnv.crash(e);
        }
    }

从上面代码可以看到它首先调用了getService方法,这个方法会返回一个IProcessManager对象,然后调用该对象的isAppProcess方法进行判断。

2.4 接下来看一下getService方法的源码

    private static IProcessManager service;

    private static IProcessManager getService() {
        if (service == null) {
            synchronized (LocalProcessManager.class) {
                if (service == null) {
                    IBinder binder = ServiceManagerNative.getService(ServiceManagerNative.PROCESS_MANAGER);
                    service = IProcessManager.Stub.asInterface(binder);
                }
            }
        }
        if (service == null) {
            throw new RuntimeException("Unable to attach ProcessManager");
        }
        return service;
    }

在getService方法中,调用了ServiceManagerNative类的getService方法获取了一个IBinder对象,然后将远程对象的代理传给了service,然后进行了返回。

2.5 接下来看一下ServiceManagerNative类的getService方法,其源码如下:

        public static IBinder getService(String name) {
        if (VirtualCore.getCore().isServiceProcess()) {
            return ServiceCache.getService(name);
        }
        IServiceFetcher fetcher = getServiceFetcher();
        if (fetcher != null) {
            try {
                return fetcher.getService(name);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        VLog.e(TAG, "GetService(%s) return null.", name);
        return null;
    }

首先调用VirtualCore类中的isServiceProcess方法判断当前进程是否为服务进程,如果是的话直接返回保存在ServiceCache类中的service。从上文分析来看,如果当前进程是服务进程就会直接返回了,不会有2.3步骤的分析了,因此此处不是服务进程,进入下面分析。通过调用getServiceFetcher方法获取一个IServiceFetcher对象,然后调用返回该对象的getService方法。

2.6 接着看一下getServiceFetcher方法的源码:

    public static IServiceFetcher getServiceFetcher() {
        Context context = VirtualCore.getCore().getContext();
        Bundle response = new ProviderCaller.Builder(context, SERVICE_CP_AUTH).methodName("@").call();
        if (response != null) {
            IBinder binder = BundleCompat.getBinder(response, ExtraConstants.EXTRA_BINDER);
            linkBinderDied(binder);
            return IServiceFetcher.Stub.asInterface(binder);
        }
        return null;
    }

首先获取了VirtualCore中的context对象,然后构建了一个ProviderCaller的一个内部类Builder对象,然后依次调用了methodName方法和call方法,最后返回了一个Bundle对象。

2.7 首先看一下内部类Builder的源码:

public static final class Builder {

        private Context context;

        private Bundle bundle = new Bundle();

        private String methodName;
        private String auth;
        private String arg;

        public Builder(Context context, String auth) {
            this.context = context;
            this.auth = auth;
        }

        public Builder methodName(String name) {
            this.methodName = name;
            return this;
        }

        public Builder arg(String arg) {
            this.arg = arg;
            return this;
        }

        public Builder addArg(String key, Object value) {
            if (value != null) {
                if (value instanceof IBinder) {
                    if (Build.VERSION.SDK_INT >= 18) {
                        bundle.putBinder(key, (IBinder) value);
                    } else {
                        //noinspection deprecation
                        bundle.putIBinder(key, (IBinder) value);
                    }
                } else if (value instanceof Boolean) {
                    bundle.putBoolean(key, (Boolean) value);
                } else if (value instanceof Integer) {
                    bundle.putInt(key, (Integer) value);
                } else if (value instanceof String) {
                    bundle.putString(key, (String) value);
                } else if (value instanceof Serializable) {
                    bundle.putSerializable(key, (Serializable) value);
                } else if (value instanceof Bundle) {
                    bundle.putBundle(key, (Bundle) value);
                } else if (value instanceof Parcelable) {
                    bundle.putParcelable(key, (Parcelable) value);
                } else {
                    throw new IllegalArgumentException("Unknown type " + value.getClass() + " in Bundle.");
                }
            }
            return this;
        }

从上面代码可以看出,其methodName方法只是将名字”@”传给了它的methodName属性,而call方法则是调用了其外部类 ProviderCaller的call方法。

2.8 ProviderCaller的call方法源码如下:

        public static Bundle call(String auth, Context context, String methodName, String arg, Bundle bundle) {
        Uri uri = Uri.parse("content://" + auth);
        ContentResolver contentResolver = context.getContentResolver();
        return contentResolver.call(uri, methodName, arg, bundle);
    }

可以看到,在该方法中最后实际工作是调用了ContentResolver类的call方法,该方法是Android系统源码中定义的方法,它可以执行在ContentProvider中暴露出来的方法,所有最后实际工作还是在provider中进行的,该流程暂时分析到这里。

2.9 接着进行2.2步的分析

    PatchManager patchManager = PatchManager.getInstance();
            patchManager.injectAll();
            patchManager.checkEnv();
            RuntimeEnv.init();
            PatchManager.fixContext(context);
            isStartUp = true;

从上面代码可以看出,首先创建了一个PatchManager类的实例,然后分别调用了改对象的injectAll方法和checkEnv方法。

2.10 首先分析PatchManager对象的injectAll方法,其源码如下:

        public void injectAll() throws Throwable {
        if (PatchManagerHolder.sInit) {
            throw new IllegalStateException("PatchManager Has been initialized.");
        }
        injectInternal();
        PatchManagerHolder.sInit = true;

    }

该方法中会去调用injectInternal方法,injectInternal方法源码如下:

    private void injectInternal() throws Throwable {
        addPatch(new ActivityManagerPatch());
        addPatch(new PackageManagerPatch());

        if (VirtualCore.getCore().isVAppProcess()) {
            // ## Fuck the MIUI Security
            if (MIUISecurityManagerPatch.needInject()) {
                addPatch(new MIUISecurityManagerPatch());
            }
            // ## End
            addPatch(HCallbackHook.getDefault());
            addPatch(AppInstrumentation.getDefault());
            addPatch(new NotificationManagerPatch());
            addPatch(new LocationManagerPatch());
            addPatch(new WindowManagerPatch());
            addPatch(new ClipBoardPatch());
            addPatch(new MountServicePatch());
            addPatch(new BackupManagerPatch());
            addPatch(new TelephonyPatch());
            addPatch(new PhoneSubInfoPatch());
            addPatch(new PowerManagerPatch());
            addPatch(new TelephonyRegistryPatch());
            addPatch(new AppWidgetManagerPatch());
            addPatch(new AccountManagerPatch());
            addPatch(new DropBoxManagerPatch());
            addPatch(new AudioManagerPatch());
            addPatch(new SearchManagerPatch());

            if (Build.VERSION.SDK_INT >= JELLY_BEAN_MR2) {
                addPatch(new VibratorPatch());
                addPatch(new WifiManagerPatch());
            }
            if (Build.VERSION.SDK_INT >= JELLY_BEAN_MR1) {
                addPatch(new UserManagerPatch());
            }

            if (Build.VERSION.SDK_INT >= JELLY_BEAN_MR1) {
                addPatch(new DisplayManagerPatch());
            }
            if (Build.VERSION.SDK_INT >= L) {
                addPatch(new InputMethodManagerPatch());
                addPatch(new MmsPatch());
                addPatch(new SessionManagerPatch());
                addPatch(new JobPatch());
                addPatch(new RestrictionPatch());
                addPatch(new CameraPatch());
            }
            if (Build.VERSION.SDK_INT >= KITKAT) {
                addPatch(new AppOpsManagerPatch());
                addPatch(new MediaRouterServicePatch());
            }
            if (Build.VERSION.SDK_INT >= LOLLIPOP_MR1) {
                addPatch(new GraphicsStatsPatch());
            }
        }
    }

在上面代码可以看出,它调用了addPatch方法将许多xxxPatch类添加了进去。addPatch源码如下:

private void addPatch(Injectable injectable) {
        injectableMap.put(injectable.getClass(), injectable);
    }   

从上面代码可以看出,addPatch方法就是讲许多的Injectable对象存放了起来,其中injectableMap的定义如下:

        private Map<Class>, Injectable> injectableMap = new HashMap<Class, Injectable>(12);    

因此,addPatch方法就是将Injectable对象存放到了了injectableMap这个Map表中。以ActivityManagerPatch()为例看一下这些xxxPatch对象。

2.11 ActivityManagerPatch类的源码如下:

    @Patch({Hook_StartActivities.class, Hook_StartActivity.class, Hook_StartActivityAsCaller.class,
        Hook_StartActivityAsUser.class, Hook_GetIntentSender.class, Hook_RegisterReceiver.class,
        Hook_GetContentProvider.class, Hook_GetContentProviderExternal.class,

        Hook_GetActivityClassForToken.class, Hook_GetTasks.class, Hook_GetRunningAppProcesses.class,

        Hook_StartService.class, Hook_StopService.class, Hook_StopServiceToken.class, Hook_BindService.class,
        Hook_UnbindService.class, Hook_PeekService.class, Hook_ServiceDoneExecuting.class, Hook_UnbindFinished.class,
        Hook_PublishService.class,

        Hook_HandleIncomingUser.class, Hook_SetServiceForeground.class,

        Hook_BroadcastIntent.class, Hook_GetCallingPackage.class, Hook_GrantUriPermissionFromOwner.class,
        Hook_CheckGrantUriPermission.class, Hook_GetPersistedUriPermissions.class, Hook_KillApplicationProcess.class,
        Hook_ForceStopPackage.class, Hook_AddPackageDependency.class, Hook_UpdateDeviceOwner.class,
        Hook_CrashApplication.class, Hook_GetPackageForToken.class,

        Hook_SetPackageAskScreenCompat.class, Hook_GetPackageAskScreenCompat.class,
        Hook_SetAppLockedVerifying.class,
        Hook_CheckPermission.class,
        Hook_PublishContentProviders.class,
        Hook_GetCurrentUser.class,
        Hook_UnstableProviderDied.class,
        Hook_GetCallingActivity.class,})
    public class ActivityManagerPatch extends PatchObject<IActivityManager, HookObject<IActivityManager>> {

    public static IActivityManager getAMN() {
        return ActivityManagerNative.getDefault();
    }

    @Override
    protected HookObject initHookObject() {
        return new HookObject(getAMN());
    }

    @Override
    public void inject() throws Throwable {

        Field f_gDefault = ActivityManagerNative.class.getDeclaredField("gDefault");
        if (!f_gDefault.isAccessible()) {
            f_gDefault.setAccessible(true);
        }
        if (f_gDefault.getType() == IActivityManager.class) {
            f_gDefault.set(null, getHookObject().getProxyObject());

        } else if (f_gDefault.getType() == Singleton.class) {

            Singleton gDefault = (Singleton) f_gDefault.get(null);
            Field f_mInstance = Singleton.class.getDeclaredField("mInstance");
            if (!f_mInstance.isAccessible()) {
                f_mInstance.setAccessible(true);
            }
            f_mInstance.set(gDefault, getHookObject().getProxyObject());
        } else {
            // 不会经过这里
            throw new UnsupportedOperationException("Singleton is not visible in AMN.");
        }

        HookBinder hookAMBinder = new HookBinder() {
            @Override
            protected IBinder queryBaseBinder() {
                return ServiceManager.getService(Context.ACTIVITY_SERVICE);
            }

            @Override
            protected IActivityManager createInterface(IBinder baseBinder) {
                return getHookObject().getProxyObject();
            }
        };
        hookAMBinder.injectService(Context.ACTIVITY_SERVICE);
    }

    @Override
    public boolean isEnvBad() {
        return getAMN() != getHookObject().getProxyObject();
    }
    }

从上面代码可以看出,ActivityManagerPatch这个类大概是用来替换获取AMS的代理对象gDefault的。暂且看到这里,再回到流程2.9中去.

2.12 接下来要执行的就是patchManager.checkEnv()方法,下面看一下checkEnv的源码

    public void checkEnv() throws Throwable {
        for (Injectable injectable : injectableMap.values()) {
            if (injectable.isEnvBad()) {
                injectable.inject();
            }
        }
    }

可以看到,在这个方法中是通过便利injectableMap中的injectable对象,然后执行了每个对象的inject方法。从2.10可以看出,其实这个injectable对象就是前面提到的xxxPatch类的对象。还是以ActivityManagerPatch类为例,首先执行它的isEnvBad方法。

2.13 ActivityManagerPatch类的isEnvBad方法源码如下:

@Override
    public boolean isEnvBad() {
        return getAMN() != getHookObject().getProxyObject();
    }

这个函数的返回值取决于getAMN方法和getHookObject().getProxyObject()方法的返回值,分别来看一下它们的作用。

2.14 getAMN方法的源码如下

    public static IActivityManager getAMN() {
        return ActivityManagerNative.getDefault();
    }

可以看到,这个方法其实返回的就是AMS的代理对象gDefault,再看一下后者的源码。

2.15 getHookObject方法的源码如下

public H getHookObject() {
        return hookObject;
    }

这个方法是ActivityManagerPatch的父类PatchObject中的方法,这里的H就是HookObject类,这里返回的就是一个HookObject类对象。由于PatchObject类是ActivityManagerPatch类的父类,所以在2.10步添加一个新的ActivityManagerPatch类对象是也会同步创建一个PatchObject类对象,看一下PatchObject类对象的源码。

2.16 首先看一下PatchObject类的无参构造方法源码

    public PatchObject() {
        this.hookObject = initHookObject();
        applyHooks();
        afterHookApply(hookObject);
    }

2.17 initHookObject方法的源码如下

    @Override
    protected HookObject initHookObject() {
        return new HookObject(getAMN());

这个方法在PatchObject类中是一个抽象方法,具体实现是在ActivityManagerPatch中,可以看到其返回一个使用AMS的代理gDefault作为参数的HookObject类对象。继续看一下HookObject类的源码。

2.18 HookObject类的构造方法如下

public HookObject(T baseObject, Class... proxyInterfaces) {
        this(baseObject == null ? null : baseObject.getClass().getClassLoader(), baseObject, proxyInterfaces);
    }

    public HookObject(ClassLoader cl, T baseObject, Class... proxyInterfaces) {
        this.mBaseObject = baseObject;
        if (mBaseObject != null) {
            if (proxyInterfaces == null) {
                proxyInterfaces = baseObject.getClass().getInterfaces();
            }
            mProxyObject = (T) Proxy.newProxyInstance(cl, proxyInterfaces, new HookHandler());
        }
    }

    public HookObject(T baseObject) {
        this(baseObject, (Class[]) null);
    }

可以看到,一共有三个构造方法,但最终会调用到第二个构造方法,在第二个构造方法中,mBaseObject对象就是我们传入的gDefault对象。同时在构造方法末尾创建了一个代理对象mProxyObject。继续2.16步的流程。

2.19 接下来要执行applyHooks()方法,这个方法的源码如下

    protected void applyHooks() {

        if (hookObject == null) {
            return;
        }

        Classextends PatchObject> clazz = getClass();
        Patch patch = clazz.getAnnotation(Patch.class);
        int version = Build.VERSION.SDK_INT;
        if (patch != null) {
            Classextends Hook>[] hookTypes = patch.value();
            for (Classextends Hook> hookType : hookTypes) {
                ApiLimit apiLimit = hookType.getAnnotation(ApiLimit.class);
                boolean needToAddHook = true;
                if (apiLimit != null) {
                    int apiStart = apiLimit.start();
                    int apiEnd = apiLimit.end();
                    boolean highThanStart = apiStart == -1 || version > apiStart;
                    boolean lowThanEnd = apiEnd == -1 || version < apiEnd;
                    if (!highThanStart || !lowThanEnd) {
                        needToAddHook = false;
                    }
                }
                if (needToAddHook) {
                    addHook(hookType);
                }
            }

        }
    }

在上面的步骤中我们已经创建了HookObject对象,所以hookObject对象不为null,接着调用getClass方法获取当前类的类型,即ActivityManagerPatch类,然后获取该类的Patch类型的注解。在2.11步的代码中可以看出,ActivityManagerPatch类注解了patch类型,因此此处的patch不为null。首先是遍历patch注解的所有成员,以Hook_StartActivities类为例,此时hookType为Hook_StartActivities类,然后获取这个类的ApiLimit.class类型的注解。在Hook_StartActivities类中没有看到ApiLimit.class类型的注解,因此apiLImit为null,而needToAddHook因此还是为true,因此需要执行addHook方法。

2.20 addHook方法的源码如下

    private void addHook(Classextends Hook> hookType) {
        try {
            Constructor> constructor = hookType.getDeclaredConstructors()[0];
            if (!constructor.isAccessible()) {
                constructor.setAccessible(true);
            }
            Hook hook;
            if (constructor.getParameterTypes().length == 0) {
                hook = (Hook) constructor.newInstance();
            } else {
                hook = (Hook) constructor.newInstance(this);
            }
            hookObject.addHook(hook);
        } catch (Throwable e) {
            throw new RuntimeException("Unable to instance Hook : " + hookType + " : " + e.getMessage());
        }
    }

可以看出,在该方法中,主要工作就是创建了一个Hook类型的对象,并将它添加到了hookObject对象中。接下来分析hookObject对象的addHook方法。

2.21 HookObject类的addHook方法源码如下所示

    @Override
    public void addHook(Hook hook) {
        if (hook != null && !TextUtils.isEmpty(hook.getName())) {
            if (internalHookMapping.containsKey(hook.getName())) {
                VLog.w(TAG, "Hook(%s) from class(%s) have been added, can't add again.", hook.getName(),
                        hook.getClass().getName());
            }
            internalHookMapping.put(hook.getName(), hook);
        }
    }

首先,Hook_StartActivities类继承了Hook类,这里传进来的就是一个Hook_StartActivities类对象,很容易判断应该直接执行internalHookMapping.put(hook.getName(), hook)这行代码。internalHookMapping是一个Map对象,存放了需要hook的类,此处将Hook_StartActivities类存放了进去。再回到主流程2.16中。

2.22 接下来要执行afterHookApply(hookObject)代码,它是一个空方法,暂时未执行。

2.23 回到流程2.13中,此时调用getProxyObject()方法,它返回的是2.18步中创建的代理对象mProxyObject。因此isEnvBad方法的返回值为true,再回到2.12中,此时就会执行injectable.inject()

2.24 以ActivityManagerPatch类为例,它的inject源码如下

@Override
    public void inject() throws Throwable {

        Field f_gDefault = ActivityManagerNative.class.getDeclaredField("gDefault");
        if (!f_gDefault.isAccessible()) {
            f_gDefault.setAccessible(true);
        }
        if (f_gDefault.getType() == IActivityManager.class) {
            f_gDefault.set(null, getHookObject().getProxyObject());

        } else if (f_gDefault.getType() == Singleton.class) {

            Singleton gDefault = (Singleton) f_gDefault.get(null);
            Field f_mInstance = Singleton.class.getDeclaredField("mInstance");
            if (!f_mInstance.isAccessible()) {
                f_mInstance.setAccessible(true);
            }
            f_mInstance.set(gDefault, getHookObject().getProxyObject());
        } else {
            // 不会经过这里
            throw new UnsupportedOperationException("Singleton is not visible in AMN.");
        }

从上面代码可以看出,这个函数就是将AMS的代理对象gDefault给替换掉,替换成2.18步创建的代理对象mProxyObject。

2.25 回到流程2.9,此时patchManager.checkEnv()执行完毕,接下来执行RuntimeEnv.init(),init方法的源码如下所示

public static void init() {
        sUIHandler = new Handler(Looper.getMainLooper());
    }   

可以看出,它只是创建了一个以MainLooper为参数的Handler对象。接下来回到流程2.9,接着执行PatchManager.fixContext(context)。

2.26 fixContext方法的源码如下

    public static void fixContext(Context context) {
        while (context instanceof ContextWrapper) {
            context = ((ContextWrapper) context).getBaseContext();
        }
        try {
            Reflect.on(context).set("mPackageManager", null);
            context.getPackageManager();
        } catch (Throwable e) {
            // Ignore
        }
    }

首先,获取了父类ContextWrapper的mBase对象,mBase是一个contextImpl对象,实现了context的功能,,然后将mBase覆盖原有context。接着调用Reflect类的on方法。

2.27 on方法的源码如下所示

    public static Reflect on(Object object) {
        return new Reflect(object);
    }   

在on方法中,直接以传入的context为参数构建了一个新的Reflect对象,接下来调用这个新的Reflect对象的set方法。

2.28 Reflect类的set方法源码如下所示

public Reflect set(String name, Object value) throws ReflectException {
        try {
            Field field = field0(name);
            field.setAccessible(true);
            field.set(object, unwrap(value));
            return this;
        } catch (Exception e) {
            throw new ReflectException(e);
        }
    }

首先调用field0方法。

2.29 field0方法的源码如下所示

    private Field field0(String name) throws ReflectException {
        Class type = type();

        // 先尝试取得公有字段
        try {
            return type.getField(name);
        }

        // 此时尝试非公有字段
        catch (NoSuchFieldException e) {
            do {
                try {
                    return accessible(type.getDeclaredField(name));
                } catch (NoSuchFieldException ignore) {
                }

                type = type.getSuperclass();
            } while (type != null);

            throw new ReflectException(e);
        }
    }

首先通过调用type方法获取上面在创建Reflect对象时所传入的context对象的类类型,然后获取该类的字段mPackageManager。回到2.28中,接下来将context对象的mPackageManager字段置空。回到流程2.26中,接下来调用context.getPackageManager()。

2.30 contextImpl类的getPackageManager方法源码如下

    @Override
            public PackageManager getPackageManager() {
                if (mPackageManager != null) {
                    return mPackageManager;
                }
                IPackageManager pm = ActivityThread.getPackageManager();
                if (pm != null) {
                   return (mPackageManager = new ApplicationPackageManager(this, pm));
                }
                return null;
            }

由于在2.28步中将context对象的mPackageManager字段置空,所以此时会创建一个新的PackageManager类对象,并将其赋给mPackageManager字段。回到2.9,将isStartUp字段置为true,表明已经启动。至此,VirtualCore.getCore().startup(base)执行完毕。

三、在VApp的onCreate方法中注册进程管理器,管理进程变化。

3.1 VApp的onCreate方法源码如下所示

@Override
    public void onCreate() {
        gDefault = this;
        super.onCreate();
        if (VirtualCore.getCore().isMainProcess()) {
            Once.initialise(this);
            LocalProcessManager.registerProcessObserver(new IProcessObserver.Stub() {
                @Override
                public void onProcessCreated(String pkg, String processName) throws RemoteException {
                    VLog.d("VProcess", "Process created: %s -> %s.", pkg, processName);
                }

                @Override
                public void onProcessDied(String pkg, String processName) throws RemoteException {
                    VLog.d("VProcess", "Process died: %s -> %s.", pkg, processName);
                }
            });
        }
    }

首先,将当前类对象传给gDefault,然后调用VirtualCore类的isMainProcess方法判断当前类是否为主进程,如果是的话再进行进一步处理。先调用Once类进行初始化,然后调用LocalProcessManager类的registerProcessObserver方法,

3.2 registerProcessObserver方法的源码如下所示

    public static void registerProcessObserver(IProcessObserver observer) {
        try {
            getService().registerProcessObserver(observer);
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

首先调用getService方法获取一个service对象,然后进一步调用了这个service对象的registerProcessObserver方法。

3.3 首先看一下gerService方法的源码

private static IProcessManager service; 
    private static IProcessManager getService() {
        if (service == null) {
            synchronized (LocalProcessManager.class) {
                if (service == null) {
                    IBinder binder = ServiceManagerNative.getService(ServiceManagerNative.PROCESS_MANAGER);
                    service = IProcessManager.Stub.asInterface(binder);
                }
            }
        }
        if (service == null) {
            throw new RuntimeException("Unable to attach ProcessManager");
        }
        return service;
    }

可以看到方法最后是调用了ServiceManagerNative的getService方法获取了一个binder对象,然后将此binder对象包装后传给service。可以看到,此处代码与2.4处相同,执行到最后会调用contentResolver的call方法来获取Bundle对象,然后从该Bundle对象中取出保存在对象里面的Binder对象。

至此,VA的Application启动过程就分析完成。

你可能感兴趣的:(Android安全相关,Android框架,VirtualApp)