Android世界第一个activity启动过程

第一次使用Markdown,感觉不错。
Android系统从按下开机键一直到launcher的出现,是一个怎样的过程,中间都做出了什么操作呢,带着这些疑问开始源码之旅。
像windows操作系统一样,每个系统的启动都会有一个引导程序,在linux中,当引导程序启动linux内核后,会加载各种驱动和数据结构,当有了驱动之后,开始加载Android系统,开始进入linux世界的第一个进程:init进程。

在init.c的main中:

    int main(int argc, char **argv){            umask(0);// 清除文件的默认属性            mkdir("/dev", 0755); // 创建文件、挂载文件等操作            ........            init_parse_config_file("/init.rc");  // 解析文件            .........    }

在init.rc文件中:(该文件在system/core/rootdir目录下)

    // 设置一些全局环境变量    export PATH /sbin:/vendor/bin:/system/sbin:/system/bin:/system/xbin    export LD_LIBRARY_PATH /vendor/lib:/system/lib    ..............    // 创建基本的文件系统结构    mkdir /data/misc 01771 system misc    ..............    // 启动一些服务    service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    socket zygote stream 666    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart media    onrestart restart netd    .............

最重要的是这个zygote进程,zygote就是一个孵化器,类似于母进程一样,可以fork出很多的子进程,是Android的一个母进程,用来启动Android的其他服务进程。当media、netd等服务进程销毁后,zygote进程会自动重启这些服务进程

在App_Main.cpp文件中:

    int main(int argc, const char* const argv[]){            ............................             bool startSystemServer = (i < argc) ?              strcmp(argv[i], "--start-system-server") == 0 : false;             setArgv0(argv0, "zygote");            set_process_name("zygote");            runtime.start("com.android.internal.os.ZygoteInit",startSystemServer);    }

在AndroidRuntime的start方法中

    void AndroidRuntime::start(const char* className, const bool startSystemServer){            ....................            //   开启java虚拟机,并加载好jni运行环境            if (startVm(&mJavaVM, &env) != 0)                 goto bail;            .............            // 利用jni与java进行交互,加载ZygoteInit类            startClass = env->FindClass(slashClassName);            if (startClass == NULL) {                LOGE("JavaVM unable to locate class '%s'\n", slashClassName);            } else {                // 利用jni调用ZygoteInit类中的main方法                startMeth = env->GetStaticMethodID(startClass, "main","([Ljava/lang/String;)V");                if (startMeth == NULL) {                    LOGE("JavaVM unable to find main() in '%s'\n", className);            } else {                env->CallStaticVoidMethod(startClass, startMeth, strArray);                if (env->ExceptionCheck())                        threadExitUncaughtException(env);            }    }

在ZygoteInit.java中:

    public static void main(String argv[]) {            // 设置Android运行时的最小堆大小5M            VMRuntime.getRuntime().setMinimumHeapSize(5 * 1024 * 1024);            ..............            // 预加载一些常用的类,这些常用的类在2.3中有1800个左右,在4.2源码中大概有2400多个常用的            // 像有些手机厂商手机的启动速度较快的,估计是对这里进行了优化            preloadClasses();            // 加载一些资源文件,array、drawable、color等xml文件            preloadResources();            ..............             if (argv[1].equals("true")) {                     //在SystemServer类中fork系统服务进程                    startSystemServer();             } else if (!argv[1].equals("false")) {                    throw new RuntimeException(argv[0] + USAGE_STRING);             }    }     private static boolean startSystemServer() throws MethodAndArgsCaller, RuntimeException {             String args[];            String ashmem_size = System.getProperty("gralloc.ashmem_size");            if ((null != ashmem_size) && (0 != ashmem_size.length())) {                args = new String[] {                    "--setuid=1000",                    "--setgid=1000",                    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",                    "--capabilities=130104352,130104352",                    "--rlimit=8,",                    "--runtime-init",                    "--nice-name=system_server",                    "com.android.server.SystemServer",                };                args[4] = args[4].concat(ashmem_size);                args[4] = args[4].concat(",");                args[4] = args[4].concat(ashmem_size);            } else {                args = new String[] {                    "--setuid=1000",                    "--setgid=1000",                    "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006",                    "--capabilities=130104352,130104352",                    "--runtime-init",                    "--nice-name=system_server",                    "com.android.server.SystemServer",                };            }            ..............................            pid = Zygote.forkSystemServer(                parsedArgs.uid, parsedArgs.gid,                parsedArgs.gids, debugFlags, rlimits,                parsedArgs.permittedCapabilities,                parsedArgs.effectiveCapabilities);    } catch (IllegalArgumentException ex) {        throw new RuntimeException(ex);    }

SystemServer类中:

     native public static void init1(String[] args);             .........             System.loadLibrary("android_servers");             init1(args);             .........     }

首先加载android_servers这个so库,这个库在于systemServer父目录同级别下的jni目录中,对应的c文件是com_android_server_SystemServer.c。然后调用库中的init1方法,

     extern "C" int system_init();    static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)    {        system_init();    }    static JNINativeMethod gMethods[] = {        { "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },    };
int register_android_server_SystemServer(JNIEnv* env){return jniRegisterNativeMethods(env, "com/android/server/SystemServer",        gMethods, NELEM(gMethods));}

我们可以看到init1被注册到了android_server_SystemServer_init1 这个方法上了,在android_server_SystemServer_init1 方法中调用了system_init方法,这个方法出现在System_init.cpp中

extern "C" status_t system_init(){// 开启传感器服务SensorService::instantiate();if (!proc->supportsProcesses()) {    AudioFlinger::instantiate();    // 启动媒体播放服务    MediaPlayerService::instantiate();    CameraService::instantiate();    AudioPolicyService::instantiate();}  // 启动Android运行时AndroidRuntime* runtime = AndroidRuntime::getRuntime();.................runtime->callStatic("com/android/server/SystemServer", "init2");.................return NO_ERROR;

在System_init.cpp类中的system_init()方法中:利用runtime 调用SystemServer的init2方法,init2方法描述如下:

public static final void init2() {    // 开始进入Android系统服务    Thread thr = new ServerThread();    thr.setName("android.server.ServerThread");    thr.start();}

在run方法中:

...........// 实例化各种系统服务ContentService.main(context,factoryTest == SystemServer.FACTORY_TEST_LOW_LEVEL);Slog.i(TAG, "System Content Providers");ActivityManagerService.installSystemProviders();Slog.i(TAG, "Battery Service");battery = new BatteryService(context);ServiceManager.addService("battery", battery);Slog.i(TAG, "Lights Service");lights = new LightsService(context);............ServiceManager.addService("vibrator", new VibratorService(context));    ............ ((ActivityManagerService)ActivityManagerNative.getDefault())            .systemReady(new Runnable() {        public void run() {            ........        });

ServerThread线程任务主要是new出系统的服务,然后添加到serviceManager统一管理,最后调用ActivityManagerService的systemReady方法中执行了mMainStack.resumeTopActivityLocked(null);也就是打开了第一个activity。

  final boolean resumeTopActivityLocked(ActivityRecord prev) {    // 寻找没有被finish掉的第一个activity    ActivityRecord next = topRunningActivityLocked(null);    final boolean userLeaving = mUserLeaving;    mUserLeaving = false;    if (next == null) {        if (mMainStack) {            // 没有activity,启动launcher            return mService.startHomeActivityLocked();        }    }    .....................  }

到此,Android世界的第一个activity已经成功启动,它就是Launcher中的主activity。

更多相关文章

  1. 一款常用的 Squid 日志分析工具
  2. GitHub 标星 8K+!一款开源替代 ls 的工具你值得拥有!
  3. RHEL 6 下 DHCP+TFTP+FTP+PXE+Kickstart 实现无人值守安装
  4. Linux 环境下实战 Rsync 备份工具及配置 rsync+inotify 实时同步
  5. 一款霸榜 GitHub 的开源 Linux 资源监视器!
  6. Android(安卓)View的onClick事件监听
  7. Android创建桌面快捷方式两种方法
  8. ReactNative中把js编译成bundle后,js引用的图片的去向
  9. Android开发最佳实践

随机推荐

  1. Android(安卓)M新特性Doze and App Stand
  2. Android(安卓)Camera 运行流程
  3. 将Gsensor lis301 driver 升级到 lis331
  4. [置顶] Android中一些优秀的博文(看过的)
  5. 在android中读取联系人信息的程序,包括读
  6. 让组件悬浮所有页面之上
  7. Android(安卓)炫酷的自定义进度条Progres
  8. Android(安卓)源码的建造者模式
  9. android 玩愤怒的小鸟等游戏的时候全屏TP
  10. Js Android(安卓)交互