Android N Phone进程启动流程

来源:互联网 发布:淘宝美工书籍推荐 编辑:程序博客网 时间:2024/05/22 05:21

本流程图基于MTK平台 Android 7.0,本流程只作为沟通学习使用

整体流程图

这里写图片描述

部分关键点说明

persistent属性

以下来自官网介绍:https://developer.android.com/guide/topics/manifest/application-element.html

android:persistentWhether or not the application should remain running at all times"true" if it should, and "false" if not. The default value is "false". Applications should not normally set this flag; persistence mode is intended only for certain system applications.

从字面上理解就是常驻进程,当这个属性为true时,该进程应该在系统启动之后由AMS启动,那这个属性值和我们的Phone进程有什么关系呢?

我们知道Phone进程的全称应该是: package=”com.android.phone” ,我们可以在 service 目录下的 Telephony 模块的 AndroidManifest 文件中看到他的定义,这个文件里面有一个名为“PhoneApp”的application,它的persistent的属性为: android:persistent=”true” ,我们通过上面的流程图可以知道,PhoneApp 通过它的 onCreate 方法,创建了PhoneGlobals,PhoneGlobals 则创建了我们的 phone,所以我们的 Phone 进程也是通过 persistent 属性来启动的。

启动流程部分关键方法

遍历所有persistent为true的进程

//ActivityManagerService.java    private void startPersistentApps(int matchFlags) {        if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;        synchronized (this) {            try {                final List<ApplicationInfo> apps = AppGlobals.getPackageManager()                        .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList(); //得到所有persistent为true的进程信息                for (ApplicationInfo app : apps) {                    if (!"android".equals(app.packageName)) {                        addAppLocked(app, false, null /* ABI override */);//逐一启动进程                    }                }            } catch (RemoteException ex) {            }        }    }

具体获取所有persistent为true的进程信息

//PackageManagerService.java    private @NonNull List<ApplicationInfo> getPersistentApplicationsInternal(int flags) {        final ArrayList<ApplicationInfo> finalList = new ArrayList<ApplicationInfo>();        // reader        synchronized (mPackages) {            final Iterator<PackageParser.Package> i = mPackages.values().iterator(); //拿到所有的package            final int userId = UserHandle.getCallingUserId();            while (i.hasNext()) {  //遍历所有的package                final PackageParser.Package p = i.next();                if (p.applicationInfo == null) continue;                final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)                        && !p.applicationInfo.isDirectBootAware();                final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)  //根据传入的flags赋值                        && p.applicationInfo.isDirectBootAware();                if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0                        && (!mSafeMode || isSystemApp(p))                        && (matchesUnaware || matchesAware)) {                    PackageSetting ps = mSettings.mPackages.get(p.packageName);                    if (ps != null) {                        ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags, //拿到对应package 的信息                                ps.readUserState(userId), userId);                        if (ai != null) {                            /// M: Add phone package at front                            if (p.packageName.equals("com.android.phone")) { //MTK加的把phone进程放到第一个,加快启动                                finalList.add(0, ai);                            } else {                                finalList.add(ai);                            }                        }                    }                }            }        }        return finalList;    }

通过 zygote 机制创建进程

//Process.java    /**     * Starts a new process via the zygote mechanism.     *     * @param processClass Class name whose static main() to run     * @param niceName 'nice' process name to appear in ps     * @param uid a POSIX uid that the new process should setuid() to     * @param gid a POSIX gid that the new process shuold setgid() to     * @param gids null-ok; a list of supplementary group IDs that the     * new process should setgroup() to.     * @param debugFlags Additional flags.     * @param targetSdkVersion The target SDK version for the app.     * @param seInfo null-ok SELinux information for the new process.     * @param abi the ABI the process should use.     * @param instructionSet null-ok the instruction set to use.     * @param appDataDir null-ok the data directory of the app.     * @param extraArgs Additional arguments to supply to the zygote process.     * @return An object that describes the result of the attempt to start the process.     * @throws ZygoteStartFailedEx if process start failed for any reason     */    private static ProcessStartResult startViaZygote(final String processClass,                                  final String niceName,                                  final int uid, final int gid,                                  final int[] gids,                                  int debugFlags, int mountExternal,                                  int targetSdkVersion,                                  String seInfo,                                  String abi,                                  String instructionSet,                                  String appDataDir,                                  String[] extraArgs)                                  throws ZygoteStartFailedEx {        synchronized(Process.class) {            ArrayList<String> argsForZygote = new ArrayList<String>();            // --runtime-args, --setuid=, --setgid=,            // and --setgroups= must go first            argsForZygote.add("--runtime-args");            argsForZygote.add("--setuid=" + uid);            argsForZygote.add("--setgid=" + gid);            if ((debugFlags & Zygote.DEBUG_ENABLE_JNI_LOGGING) != 0) {                argsForZygote.add("--enable-jni-logging");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_SAFEMODE) != 0) {                argsForZygote.add("--enable-safemode");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_DEBUGGER) != 0) {                argsForZygote.add("--enable-debugger");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_CHECKJNI) != 0) {                argsForZygote.add("--enable-checkjni");            }            if ((debugFlags & Zygote.DEBUG_GENERATE_DEBUG_INFO) != 0) {                argsForZygote.add("--generate-debug-info");            }            if ((debugFlags & Zygote.DEBUG_ALWAYS_JIT) != 0) {                argsForZygote.add("--always-jit");            }            if ((debugFlags & Zygote.DEBUG_NATIVE_DEBUGGABLE) != 0) {                argsForZygote.add("--native-debuggable");            }            if ((debugFlags & Zygote.DEBUG_ENABLE_ASSERT) != 0) {                argsForZygote.add("--enable-assert");            }            if (mountExternal == Zygote.MOUNT_EXTERNAL_DEFAULT) {                argsForZygote.add("--mount-external-default");            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_READ) {                argsForZygote.add("--mount-external-read");            } else if (mountExternal == Zygote.MOUNT_EXTERNAL_WRITE) {                argsForZygote.add("--mount-external-write");            }            argsForZygote.add("--target-sdk-version=" + targetSdkVersion);            //TODO optionally enable debuger            //argsForZygote.add("--enable-debugger");            // --setgroups is a comma-separated list            if (gids != null && gids.length > 0) {                StringBuilder sb = new StringBuilder();                sb.append("--setgroups=");                int sz = gids.length;                for (int i = 0; i < sz; i++) {                    if (i != 0) {                        sb.append(',');                    }                    sb.append(gids[i]);                }                argsForZygote.add(sb.toString());            }            if (niceName != null) {                argsForZygote.add("--nice-name=" + niceName);            }            if (seInfo != null) {                argsForZygote.add("--seinfo=" + seInfo);            }            if (instructionSet != null) {                argsForZygote.add("--instruction-set=" + instructionSet);            }            if (appDataDir != null) {                argsForZygote.add("--app-data-dir=" + appDataDir);            }            argsForZygote.add(processClass);            if (extraArgs != null) {                for (String arg : extraArgs) {                    argsForZygote.add(arg);                }            }            return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi), argsForZygote);        }    }

和AMS建立通信

//ActivityThread.java private void attach(boolean system) {        sCurrentActivityThread = this;        mSystemThread = system;        if (!system) {            ViewRootImpl.addFirstDrawHandler(new Runnable() {                @Override                public void run() {                    ensureJitEnabled();                }            });            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",                                                    UserHandle.myUserId());            RuntimeInit.setApplicationObject(mAppThread.asBinder());//传入当前进程主线程的binder            final IActivityManager mgr = ActivityManagerNative.getDefault();            try {                mgr.attachApplication(mAppThread);//和AMS通过binder建立通信            } catch (RemoteException ex) {                throw ex.rethrowFromSystemServer();            }            //.............省略部分代码    }

执行对应application的OnCreate方法

//ActivityThread.javaprivate void handleBindApplication(AppBindData data) {        // Register the UI Thread as a sensitive thread to the runtime.        //......省略部分代码            try {                mInstrumentation.callApplicationOnCreate(app);//执行application的OnCreate方法            } catch (Exception e) {                if (!mInstrumentation.onException(app, e)) {                    throw new RuntimeException(                        "Unable to create application " + app.getClass().getName()                        + ": " + e.toString(), e);                }            }        } finally {            StrictMode.setThreadPolicy(savedPolicy);        }    }

上面主要介绍了从AMS到PhoneApp的流程,具体介绍了一下系统是如何启动persistent为true的进程的,后续会介绍Phone进程启动过程中的一些关键类和它们的作用。

0 0
原创粉丝点击