前言

对于Android开发,干上几年后,都要进阶,或者间接转行了。如果你还在干Android,想要进阶 对Framework的理解是必不可少的过程,上面就开始进入明天的主题吧。

咱们晓得,对于任何程序语言而言,入口个别都是main函数。

那Android的程序入口在哪呢? 他的main函数是怎么启动起来的呢?

可能相熟Android的同学,晓得一个应用程序的入口在ActivityThread中,那有个问题,ActivityThread中的main函数是何时被谁被调用的呢?

将从本文中找到以上答案,如果曾经相熟了此过程的同学,能够在复习一下。

Android架构

Android 平台的根底是 Linux 内核。Android Runtime (ART/Dalvik) 依附 Linux 内核来执行底层性能,例如线程和低层内存治理等。

而在Android Runtime之上就是咱们常常接触的Java API Framework层, 如下图是Android的零碎架构图

明天的主题不是此架构图的各个局部解释,而是离应用层更近的Framework层启动过程剖析。

Android Framework概述

如果咱们这里抛开Android架构图,那广义的Framewrok次要蕴含那些内容呢?

按我的了解,能够分为三个局部 服务端,客户端,和依赖Linux底层能力的驱动局部。

服务端

次要是ActivityManagerService(AMS), WindowManagerService(WMS),PackageM anerService(PMS)

  • AMS 次要用于治理所有应用程序的Activity
  • WMS 治理各个窗口,暗藏,显示等
  • PMS 用来治理跟踪所有利用APK,装置,解析,管制权限等.

还有用来解决触摸音讯的两个类KeyInputQueue和InputDispatchThread,一个用来读音讯,一个用来散发音讯.

客户端

次要包含ActivityThread,Activity,DecodeView及父类View,PhoneWindow,ViewRootImpl及外部类W等

  • ActivityThread次要用来和AMS通信的客户端,Activity是咱们编写利用比拟相熟的类

依赖Linux底层能力的驱动

次要是SurfaceFlingger(SF)和Binder驱动

  • 每一个窗口都对应一个Surface,SF驱动的作用就是把每一个Surface显示到同一个屏幕上
  • Binder 内核驱动的作用,就是为下面的服务端和客户端(或者服务端和服务端之间),提供IPC通信用的。

Zygote

零碎中运行的第一个Dalvik虚拟机程序叫做zygote,该名称的意义是“一个卵”,,因为接下来的所有 Dalvik虚拟机过程都是通过这个“卵” 孵化进去的。

zygote过程中蕴含两个次要模块,别离如下:

  • Socket服务端。该 Socket服务端用于接管启动新的Dalvik过程的命令。
  • Framework共享类及共享资源。当zygote过程启动后,会装载一些共享的类及资源,其中共享类是在preload-classes文件中被定义,共享资源是在preload-resources中被定义。因为zygote过程用于孵化出其余Dalvik过程,因而,这些类和资源装载后,新的Dalvik过程就不须要再装载这些类和资源了,这也就是所谓的共享。

zygote过程对应的具体程序是app\_rocess,该程序存在于system/bin目录下,启动该程序的指令是 在 init.rc中进行配置的。

Zygote 有️两个优良的特点

  • 每fork出的一个过程都是一个Dalvik虚拟机,独立的过程能够避免一个程序的解体导致所有程序都解体,这种虚拟机相似Java虚拟机,对于程序员来说,能够间接应用Java开发利用
  • zygote过程事后会装载共享类和共享资源,这些类及资源实际上就是SDK中定义的大部分类和资源。因而,当通过zygote孵化出新的过程后,新的APK过程只须要去装载A PK 本身蕴含的类和资源即可,这就无效地解决了多个APK共享Framework资源的问题。

SystemServer

zygote孵化出的第一个Dalvik过程叫做SystemServer,SystemServer仅仅是该过程的别名,而该过程具体对应的程序仍然是app\_process,因为SystemServer是从app\_process中孵化进去的。

SystemServer中创立了一个Socket客户端,并有AmS负责管理该客户端,之后所有的Dalvik过程都将通过该Socket客户端间接被启动。当须要启动新的APK过程时,AmS中会通过该Socket客户端向 zygote过程的Socket服务端发送一个启动命令,然 后 zygote会孵化出新的过程。 下面提到的服务端,AMS,PMS,WMS等都是在SystemServer中启动的.

Android Framework 源头

操作系统的个别启动流程,分为三个步骤

  1. 开机通电后,加载bootloader程序
  2. 操作系统内核初始化
  3. 执行第一个应用程序

Android 零碎是基于Linux 内核Kernel,后面Linux bootloader这里不做介绍,间接介绍操作系统内核初始化,在这个时候,它会加载init.rc文件.

init.rc文件

在Android根目录上面,能够间接找到init.rc

generic_x86:/ # lsacct     bin        cache   config data         dev init            init.rc              init.usb.rc      lost+found mnt oem  product sdcard  sys    ueventd.rc adb_keys bugreports charger d      default.prop etc init.environ.rc init.usb.configfs.rc init.zygote32.rc metadata   odm proc sbin    storage system vendor     

关上init.rc

generic_x86:/ # cat init.rc# ..... 省略其余 # Now we can start zygote for devices with file based encryptiontrigger zygote-start# It is recommended to put unnecessary data/ initialization from post-fs-data# to start-zygote in device's init.rc to unblock zygote start.on zygote-start     # A/B update verifier that marks a successful boot.    exec_start update_verifier_nonencrypted    start netd    start zygote    start zygote_secondaryon property:vold.decrypt=trigger_restart_framework    stop surfaceflinger# 启动SF    start surfaceflinger  # ..... 省略其余 media(媒体)  network(网络)等启动

也就是在 init.rc时,启动Android 内核。

app\_process

Android 内核也是main办法开始,他的main办法在 frameworks/base/cmds/app\_process/app\_main.cpp下

int main(int argc, char* const argv[]){    ...    //初始化AndroidRuntime    AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));    bool zygote = false;    bool startSystemServer = false;    bool application = false;    String8 niceName;    String8 className;    // 依据参数具体判断启动那个服务    ++i;  // Skip unused "parent dir" argument.    while (i < argc) {        const char* arg = argv[i++];        if (strcmp(arg, "--zygote") == 0) {            zygote = true;            niceName = ZYGOTE_NICE_NAME;        } else if (strcmp(arg, "--start-system-server") == 0) {            startSystemServer = true;        } else if (strcmp(arg, "--application") == 0) {            application = true;        } else if (strncmp(arg, "--nice-name=", 12) == 0) {            niceName.setTo(arg + 12);        } else if (strncmp(arg, "--", 2) != 0) {            className.setTo(arg);            break;        } else {            --i;            break;        }    }    if (!className.isEmpty()) {        args.add(application ? String8("application") : String8("tool"));        runtime.setClassNameAndArgs(className, argc - i, argv + i);    }else{        ....        //启动SystemServer        if (startSystemServer) {            args.add(String8("start-system-server"));        }    }    ....     if (zygote) {       //启动Zygote        runtime.start("com.android.internal.os.ZygoteInit", args, zygote);    } else if (className) {        runtime.start("com.android.internal.os.RuntimeInit", args, zygote);    } else {        fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");    }}

在这个Main办法中,先初始化了AppRuntime,他的父类是AndroidRuntime。而后咱们看到了启动了Java类ZygoteInit。

那c++代码里怎么启动Java类呢,咱们持续看 start办法

void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote){   ...   //启动Java虚拟机     if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {        return;    }    ...    //找到Java 外面的Main办法     jmethodID startMeth = env->GetStaticMethodID(startClass, "main",            "([Ljava/lang/String;)V");        if (startMeth == NULL) {            ALOGE("JavaVM unable to find main() in '%s'\n", className);            /* keep going */        } else {        //执行Main办法            env->CallStaticVoidMethod(startClass, startMeth, strArray);    }    ....    }

能够看到最初先创立了Java虚拟机,调用了Java的main办法,是不是感觉有些相熟感了。

ZygoteInit

下面介绍到,会启动Java的ZygoteInit类,那他外面干了些什么呢? 咱们来看一下要害代码,还是从Main办法开始

//ZygoteInit.java  public static void main(String argv[]) {    ZygoteServer zygoteServer = new ZygoteServer();    ZygoteHooks.startZygoteNoThreadCreation();    //创立socket    zygoteServer.createZygoteSocket(socketName);    Zygote.createBlastulaSocket(blastulaSocketName);    if (!enableLazyPreload) {            bootTimingsTraceLog.traceBegin("ZygotePreload");            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,            SystemClock.uptimeMillis());            //预加载系统资源            preload(bootTimingsTraceLog);            EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,                    SystemClock.uptimeMillis());            bootTimingsTraceLog.traceEnd(); // ZygotePreload    } else {        Zygote.resetNicePriority();    }    //fork SystemServer过程    if (startSystemServer) {        Runnable r = forkSystemServer(abiList, socketName, zygoteServer);        // child (system_server) process.        if (r != null) {            r.run();            return;        }    }    //期待Socket的接入    if (caller == null) {        Log.i(TAG, "Accepting command socket connections");        // The select loop returns early in the child process after a fork and        // loops forever in the zygote.        caller = zygoteServer.runSelectLoop(abiList);    }

正文写了大略Zygote 启动外面的初始化内容

  • 创立Socket
  • 加载系统资源
  • 启动SystemServer
  • runSelectLoop 期待socket接入,开始执行fork新的过程.

SystemServer

上面持续看SystemServer 启动的过程,从Main办法开始

//SystemServer.java   /**     * The main entry point from zygote.     */    public static void main(String[] args) {        new SystemServer().run();    }

很简略,创立一个本人的对象,并执行run办法,看一下run办法

private void run() {    ...    if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {        Slog.w(TAG, "System clock is before 1970; setting to 1970.");        SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);    }    VMRuntime.getRuntime().clearGrowthLimit();    // The system server has to run all of the time, so it needs to be    // as efficient as possible with its memory usage.    VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);    android.os.Process.setThreadPriority(                android.os.Process.THREAD_PRIORITY_FOREGROUND);    android.os.Process.setCanSelfBackground(false);    Looper.prepareMainLooper();   // Create the system service manager.    mSystemServiceManager = new SystemServiceManager(mSystemContext);    mSystemServiceManager.setStartInfo(mRuntimeRestart,            mRuntimeStartElapsedTime, mRuntimeStartUptime);    LocalServices.addService(SystemServiceManager.class, mSystemServiceManager);   try {        traceBeginAndSlog("StartServices");        startBootstrapServices();        startCoreServices();        startOtherServices();        SystemServerInitThreadPool.shutdown();    } catch (Throwable ex) {           Slog.e("System", "******************************************");            Slog.e("System", "************ Failure starting system services", ex);            throw ex;    } finally {        traceEnd();    }    Looper.loop();    throw new RuntimeException("Main thread loop unexpectedly exited");}

run办法外面次要进行了设置手机工夫,设置虚拟机内存大小,创立音讯循环Looper,创立SystemServiceManager等,最次要的是启动了各类服务,咱们接着看一下startBootstrapServices ,startCoreServices,startOtherServices办法

private void startBootstrapServices() {    Installer installer = mSystemServiceManager.startService(Installer.class);    mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);    mActivityManagerService = mSystemServiceManager.startService(                ActivityManagerService.Lifecycle.class).getService();    mActivityManagerService.setSystemServiceManager(mSystemServiceManager);    mActivityManagerService.setInstaller(installer);    ....}private void startCoreServices() {    ...     mSystemServiceManager.startService(BatteryService.class);     ...} private void startOtherServices() {        final Context context = mSystemContext;        VibratorService vibrator = null;        DynamicAndroidService dynamicAndroid = null;        IStorageManager storageManager = null;        NetworkManagementService networkManagement = null;        IpSecService ipSecService = null;        NetworkStatsService networkStats = null;        NetworkPolicyManagerService networkPolicy = null;        ConnectivityService connectivity = null;        NsdService serviceDiscovery= null;        WindowManagerService wm = null;        SerialService serial = null;        NetworkTimeUpdateService networkTimeUpdater = null;        InputManagerService inputManager = null;        TelephonyRegistry telephonyRegistry = null;        ConsumerIrService consumerIr = null;        MmsServiceBroker mmsService = null;        HardwarePropertiesManagerService hardwarePropertiesService = null;        ....}

在这些办法中启动了,咱们的外围服务,和罕用服务。 代码中也能够看到AMS,PMS,WMS等相干服务.

Launcher启动介绍

个别服务启动实现后,就会想继调用systemReady()办法。 在SysytemServer startOtherServices中看到一个监听回调

mActivityManagerService.systemReady(() -> {  try {        startSystemUi(context, windowManagerF);    } catch (Throwable e) {        reportWtf("starting System UI", e);    }  }}static final void startSystemUi(Context context, WindowManagerService windowManager) {        Intent intent = new Intent();        intent.setComponent(new ComponentName("com.android.systemui",                    "com.android.systemui.SystemUIService"));        intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);        //Slog.d(TAG, "Starting service: " + intent);        context.startServiceAsUser(intent, UserHandle.SYSTEM);        windowManager.onSystemUiStarted();}

而Ams启动实现后,显示Launcher

//AMS.java public void systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) { ...     startHomeActivityLocked(currentUserId, "systemReady");     //     mStackSupervisor.resumeFocusedStackTopActivityLocked(); ... }

其实到这里大抵流程就介绍完了,然而文章开始的ActivityThread的main办法是何时被调用的,还没答复,这里不具体开展,简略答复一些.

ActivityThread的main办法如何被调用的?

AMS是治理Activity的启动完结等,查看AMS代码,当以后启动的APP没有创立过程时,会最终调用到ZygoteProcess,而后向 Zygote发送一个socket申请。

resumeTopActivityLocked -> startProcessLocked -> Process.start() -> ZygoteProcess.start() -> ZygoteProcess.startViaZygote() —> ZygoteProcess.zygoteSendArgsAndGetResult()

接下来,看一下大抵代码

//AMS.javaprivate final boolean startProcessLocked(ProcessRecord app, String hostingType,            String hostingNameStr, boolean disableHiddenApiChecks, String abiOverride) {            //这里entryPoint为ActivityThread     final String entryPoint = "android.app.ActivityThread";    return startProcessLocked(hostingType, hostingNameStr, entryPoint, app, uid, gids,                    runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith,                    startTime);    }
//ZygoteProcess.javaprivate Process.ProcessStartResult startViaZygote(final String processClass,... ){    ArrayList<String> argsForZygote = new ArrayList<String>();    argsForZygote.add("--runtime-args");    argsForZygote.add("--setuid=" + uid);    argsForZygote.add("--setgid=" + gid);    argsForZygote.add("--runtime-flags=" + runtimeFlags);    argsForZygote.add("--target-sdk-version=" + targetSdkVersion);    if (startChildZygote) {        argsForZygote.add("--start-child-zygote");    }    argsForZygote.add(processClass);    synchronized(mLock) {        return zygoteSendArgsAndGetResult(openZygoteSocketIfNeeded(abi),                                              useBlastulaPool,                                              argsForZygote);    }}//发动Socket申请,给Zygoteprivate static Process.ProcessStartResult zygoteSendArgsAndGetResult(        ArrayList<String> args,..){    blastulaSessionSocket = zygoteState.getBlastulaSessionSocket();    final BufferedWriter blastulaWriter = new BufferedWriter(            new OutputStreamWriter(blastulaSessionSocket.getOutputStream()),                                Zygote.SOCKET_BUFFER_SIZE);    final DataInputStream blastulaReader =    new DataInputStream(blastulaSessionSocket.getInputStream());    blastulaWriter.write(msgStr);    blastulaWriter.flush();    ...}

最终 Zygote收到申请调用ZygoteInit中zygoteinit办法

//ZygoteInit.java public static final Runnable zygoteInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {        if (RuntimeInit.DEBUG) {            Slog.d(RuntimeInit.TAG, "RuntimeInit: Starting application from zygote");        }        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ZygoteInit");        RuntimeInit.redirectLogStreams();        RuntimeInit.commonInit();        ZygoteInit.nativeZygoteInit();        return RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);    }

在 RuntimeInit中findStaticMain,最初在ZygoteInit中执行最终返回的这个Runnable,达到调用main办法的目标.

protected static Runnable applicationInit(int targetSdkVersion, String[] argv,            ClassLoader classLoader) {        nativeSetExitWithoutCleanup(true);        VMRuntime.getRuntime().setTargetHeapUtilization(0.75f);        VMRuntime.getRuntime().setTargetSdkVersion(targetSdkVersion);        final Arguments args = new Arguments(argv);        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);        return findStaticMain(args.startClass, args.startArgs, classLoader);    }protected static Runnable findStaticMain(String className, String[] argv,            ClassLoader classLoader) {        ..        m = cl.getMethod("main", new Class[] { String[].class });        return new MethodAndArgsCaller(m, argv);    }

本文转自 https://www.jianshu.com/p/5ba93dee3dfd,如有侵权,请分割删除。

相干视频举荐:

【2021最新版】Android studio装置教程+Android(安卓)零基础教程视频(适宜Android 0根底,Android初学入门)含音视频_哔哩哔哩_bilibili

【 Android进阶教程】——Framework面试必问的Handler源码解析_哔哩哔哩_bilibili

Android进阶零碎学习——Gradle入门与我的项目实战_哔哩哔哩_bilibili

Android架构设计原理与实战——Jetpack联合MVP组合利用开发一个优良的APP!_哔哩哔哩_bilibili