精华内容
下载资源
问答
  • Android系统进程优先级排序原因

    千次阅读 2015-09-20 17:21:08
    最近初学了Android系统进程概念以及进程的排序,了解了进程在系统内部的工作流程以及原理。 下面是自己的理解和归纳 按优先级依次排序为: 1.前台进程:  是Android系统中最重要的进程,是与用户正在交互的...

    最近初学了Android系统的进程概念以及进程的排序,了解了进程在系统内部的工作流程以及原理。

    下面是自己的理解和归纳

    按优先级依次排序为:

    1.前台进程:

                  是Android系统中最重要的进程,是与用户正在交互的进程,所以优先级最高。

    2.可见进程:

     可见进程部分程序界面是可见的,有可能被用户回调,优先级仅次于前台进程。

    3.服务进程:

    这里要注意一点:Android系统除非不能保证前台进程或可见进程所必要的资源,否则不会强行清除服务进程,其可能提供用户所关心的重要功能。

    所以服务进程的优先级次于可见进程。

    4.后台进程:

    已不包含任何已启动的服务与Activity,优先级较低。

    5.空进程:

    不包含任何活跃组件,很大可能会被系统清除,优先级最低。

    展开全文
  • init进程android系统中用户空间的第一个进程 目录:android/system/core/init 职责:创建Zygote和属性服务等 2.Android系统启动流程 1.启动电源 -- 引导芯片开始从预定义扇区开始执行(固化在ROM),加载...

    Init进程

    1.简介:

        init进程是android系统中用户空间的第一个进程

        目录:android/system/core/init

        职责:创建Zygote和属性服务等

    2.Android系统启动流程

        1.启动电源 -- 引导芯片开始从预定义扇区开始执行(固化在ROM),加载引导程序BootLoader到RAM执行

         2.BootLoader -- Android系统开始运行前的一个小程序,作用是把系统os拉起并运行

         3.Linux内核启动 -- 内核完成系统设置后寻找init文件,启动root进程或系统第一个进程

         4.启动init进程

    3.init入口函数分析

        system/core/init/init.cpp

        步骤:创建文件并挂载 -- 初始化属性相关资源 -- 启动属性服务 -- 解析init.rc

    4.init.rc

        system/core/i/rootdir/init.rc

        .rc是一个配置文件,由AIL编写的脚本

        Android7.0后对rc文件进行了拆分,每个服务一个rc文件 -- Zygote服务在init.Zygote.rc中定义system/core/init/init.cpp

    5.init启动Zygote

        init/builtins.cpp

        init/service.cpp

        进入cmds/app_process/app_main.cpp目录启动Zygote

     

    6.属性服务

    init/property_service.cpp

        类似windows注册表,采用键值对记录用户/软件的使用信息,即使软件/系统重启也能根据注册表记录进行相应的初始化工作

        在init.cpp中 property_init() / start_property_service() 方法与属性服务相关(初始化属性服务配置/启动属性服务)

        创建非阻塞Socket并调用Lister对其监听,这样创建的socket就成了server

    init进程总结:

        1.创建文件并挂载

        2.初始化和启动属性服务

        3.解析ini.rc配置文件并启动Zygote 进程

     

    Zygote进程

    通过JNI调用ZygoteInit的main函数后,Zygote便进入了Java框架层 -- Zygote开创了Java框架层

    base/core/java/com/android/internal/os/ZygoteInit.java

    base/core/java/com/android/internal/os/RuntimeInit.java

    SystemServer进程

        启动binder线程池 -- SystemServer进程就可以使用binder与其他线程通信了

        创建 SystemServiceManager -- 对系统的服务进行创建启动和生命周期的管理

        启动系统服务

        ServiceManager -- 用来管理系统中的各种service,用于系统C/S架构中的Binder机制通信

                      C端要使用某个服务 -- 到ServiceManager查询Service的相关信息 -- 根据信息与Service所在进程建立通讯通路 -- 使用

     

    ActivityManagerService将Launcher启动起来

    systemServer启动过程会启动PackagerManagerService,PMS启动后将系统app安装完成

     

     

    Launcher启动

    android系统启动的作后一步是启动一个Launcher应用程序,用来显示系统中已经安装的应用程序

    Luncher在启动过程中会请求PackageManagerService返回系统中已安装的app信息,并将其封装成一个快捷图标显示在系统屏幕

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 需求:当前存在一个系统进程,需要获取当前页面的flags(getWindow.setFlags()进去的)属性,通过相关属性进行相应的业务操作。 问题:系统进程怎么获取当前系统展示window的flags属性,当前展示页面是其他apk的
  • Android系统进程Zygote启动过程的源代码分析

    万次阅读 多人点赞 2011-09-19 00:59:08
    Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧。由于Zygote进程Android系统中有着如此重要的地位,...

            在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧。由于Zygote进程在Android系统中有着如此重要的地位,本文将详细分析它的启动过程。

    《Android系统源代码情景分析》一书正在进击的程序员网(http://0xcc0xcd.com)中连载,点击进入!

            在前面一篇文章Android应用程序进程启动过程的源代码分析中,我们看到了,当ActivityManagerService启动一个应用程序的时候,就会通过Socket与Zygote进程进行通信,请求它fork一个子进程出来作为这个即将要启动的应用程序的进程;在前面两篇文章Android应用程序安装过程源代码分析Android系统默认Home应用程序(Launcher)的启动过程源代码分析中,我们又看到了,系统中的两个重要服务PackageManagerService和ActivityManagerService,都是由SystemServer进程来负责启动的,而SystemServer进程本身是Zygote进程在启动的过程中fork出来的。

            我们知道,Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的进程都是直接或者间接地由init进程fork出来的。Zygote进程也不例外,它是在系统启动的过程,由init进程创建的。在系统启动脚本system/core/rootdir/init.rc文件中,我们可以看到启动Zygote进程的脚本命令:

    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
    
            前面的关键字service告诉init进程创建一个名为"zygote"的进程,这个zygote进程要执行的程序是/system/bin/app_process,后面是要传给app_process的参数。

            接下来的socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源,这样,系统启动后,我们就可以在/dev/socket目录下看到有一个名为zygote的文件。这里定义的socket的类型为unix domain socket,它是用来作本地进程间通信用的,具体可以参考前面一篇文章Android学习启动篇提到的一书《Linux内核源代码情景分析》的第七章--基于socket的进程间通信。前面我们说到的ActivityManagerService就是通这个socket来和zygote进程通信请求fork一个应用程序进程的了。

            最后的一系列onrestart关键字表示这个zygote进程重启时需要执行的命令。

            关于init.rc文件的更多信息,请参考system/core/init/readme.txt文件。

            了解了这个信息之后,我们就知道Zygote进程要执行的程序便是system/bin/app_process了,它的源代码位于frameworks/base/cmds/app_process/app_main.cpp文件中,入口函数是main。在继续分析Zygote进程启动的过程之前,我们先来看看它的启动序列图:


            下面我们就详细分析每一个步骤。

            Step 1. app_process.main

            这个函数定义在frameworks/base/cmds/app_process/app_main.cpp文件中:

    int main(int argc, const char* const argv[])
    {
    	// These are global variables in ProcessState.cpp
    	mArgC = argc;
    	mArgV = argv;
    
    	mArgLen = 0;
    	for (int i=0; i<argc; i++) {
    		mArgLen += strlen(argv[i]) + 1;
    	}
    	mArgLen--;
    
    	AppRuntime runtime;
    	const char *arg;
    	argv0 = argv[0];
    
    	// Process command line arguments
    	// ignore argv[0]
    	argc--;
    	argv++;
    
    	// Everything up to '--' or first non '-' arg goes to the vm
    
    	int i = runtime.addVmArguments(argc, argv);
    
    	// Next arg is parent directory
    	if (i < argc) {
    		runtime.mParentDir = argv[i++];
    	}
    
    	// Next arg is startup classname or "--zygote"
    	if (i < argc) {
    		arg = argv[i++];
    		if (0 == strcmp("--zygote", arg)) {
    			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);
    		} else {
    			set_process_name(argv0);
    
    			runtime.mClassName = arg;
    
    			// Remainder of args get passed to startup class main()
    			runtime.mArgC = argc-i;
    			runtime.mArgV = argv+i;
    
    			LOGV("App process is starting with pid=%d, class=%s.\n",
    				getpid(), runtime.getClassName());
    			runtime.start();
    		}
    	} else {
    		LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");
    		fprintf(stderr, "Error: no class name or --zygote supplied.\n");
    		app_usage();
    		return 10;
    	}
    
    }
            这个函数的主要作用就是创建一个AppRuntime变量,然后调用它的start成员函数。AppRuntime这个类我们在 Android应用程序进程启动过程的源代码分析一文中已经有过介绍了,它同样是在frameworks/base/cmds/app_process/app_main.cpp文件中定义:

    class AppRuntime : public AndroidRuntime
    {
    	......
    };
            它约继承于AndroidRuntime类, AndroidRuntime类定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

    ......
    
    static AndroidRuntime* gCurRuntime = NULL;
    
    ......
    
    AndroidRuntime::AndroidRuntime()
    {
    	......
    
    	assert(gCurRuntime == NULL);        // one per process
    	gCurRuntime = this;
    }
            当AppRuntime对象创建时,会调用其父类AndroidRuntime的构造函数,而在AndroidRuntime类的构造函数里面,会将this指针保存在静态全局变量gCurRuntime中,这样,当其它地方需要使用这个AppRuntime对象时,就可以通过同一个文件中的这个函数来获取这个对象的指针:

    AndroidRuntime* AndroidRuntime::getRuntime()
    {
        return gCurRuntime;
    }
    
            回到上面的main函数中,由于我们在init.rc文件中,设置了app_process启动参数--zygote和--start-system-server,因此,在main函数里面,最终会执行下面语句:

        runtime.start("com.android.internal.os.ZygoteInit",
    	startSystemServer);
            这里的参数startSystemServer为true,表示要启动SystemServer组件。由于AppRuntime没有实现自己的start函数,它继承了父类AndroidRuntime的start函数,因此,下面会执行AndroidRuntime类的start函数。

            Step 2. AndroidRuntime.start

            这个函数定义在frameworks/base/core/jni/AndroidRuntime.cpp文件中:

    /*
    * Start the Android runtime.  This involves starting the virtual machine
    * and calling the "static void main(String[] args)" method in the class
    * named by "className".
    */
    void AndroidRuntime::start(const char* className, const bool startSystemServer)
    {
    	......
    
    	char* slashClassName = NULL;
    	char* cp;
    	JNIEnv* env;
    
    	......
    
    	/* start the virtual machine */
    	if (startVm(&mJavaVM, &env) != 0)
    		goto bail;
    
    	/*
    	* Register android functions.
    	*/
    	if (startReg(env) < 0) {
    		LOGE("Unable to register all android natives\n");
    		goto bail;
    	}
    
    	/*
    	* We want to call main() with a String array with arguments in it.
    	* At present we only have one argument, the class name.  Create an
    	* array to hold it.
    	*/
    	jclass stringClass;
    	jobjectArray strArray;
    	jstring classNameStr;
    	jstring startSystemServerStr;
    	stringClass = env->FindClass("java/lang/String");
    	assert(stringClass != NULL);
    	strArray = env->NewObjectArray(2, stringClass, NULL);
    	assert(strArray != NULL);
    	classNameStr = env->NewStringUTF(className);
    	assert(classNameStr != NULL);
    	env->SetObjectArrayElement(strArray, 0, classNameStr);
    	startSystemServerStr = env->NewStringUTF(startSystemServer ?
    		"true" : "false");
    	env->SetObjectArrayElement(strArray, 1, startSystemServerStr);
    
    	/*
    	* Start VM.  This thread becomes the main thread of the VM, and will
    	* not return until the VM exits.
    	*/
    	jclass startClass;
    	jmethodID startMeth;
    
    	slashClassName = strdup(className);
    	for (cp = slashClassName; *cp != '\0'; cp++)
    		if (*cp == '.')
    			*cp = '/';
    
    	startClass = env->FindClass(slashClassName);
    	if (startClass == NULL) {
    		......
    	} else {
    		startMeth = env->GetStaticMethodID(startClass, "main",
    			"([Ljava/lang/String;)V");
    		if (startMeth == NULL) {
    			......
    		} else {
    			env->CallStaticVoidMethod(startClass, startMeth, strArray);
    			......
    		}
    	}
    
    	......
    }

            这个函数的作用是启动Android系统运行时库,它主要做了三件事情,一是调用函数startVM启动虚拟机,二是调用函数startReg注册JNI方法,三是调用了com.android.internal.os.ZygoteInit类的main函数。

            Step 3. ZygoteInit.main

            这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	public static void main(String argv[]) {
    		try {
    			......
    
    			registerZygoteSocket();
    			
    			......
    
    			......
    
    			if (argv[1].equals("true")) {
    				startSystemServer();
    			} else if (!argv[1].equals("false")) {
    				......
    			}
    
    			......
    
    			if (ZYGOTE_FORK_MODE) {
    				......
    			} else {
    				runSelectLoopMode();
    			}
    
    			......
    		} catch (MethodAndArgsCaller caller) {
    			......
    		} catch (RuntimeException ex) {
    			......
    		}
    	}
    
    	......
    }
             它主要作了三件事情,一个调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯,二是调用startSystemServer函数来启动SystemServer组件,三是调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。

             Step 4. ZygoteInit.registerZygoteSocket

             这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	/**
    	* Registers a server socket for zygote command connections
    	*
    	* @throws RuntimeException when open fails
    	*/
    	private static void registerZygoteSocket() {
    		if (sServerSocket == null) {
    			int fileDesc;
    			try {
    				String env = System.getenv(ANDROID_SOCKET_ENV);
    				fileDesc = Integer.parseInt(env);
    			} catch (RuntimeException ex) {
    				......
    			}
    
    			try {
    				sServerSocket = new LocalServerSocket(
    					createFileDescriptor(fileDesc));
    			} catch (IOException ex) {
    				.......
    			}
    		}
    	}
    		
    	......
    }
             这个socket接口是通过文件描述符来创建的,这个文件描符代表的就是我们前面说的/dev/socket/zygote文件了。这个文件描述符是通过环境变量ANDROID_SOCKET_ENV得到的,它定义为:

    public class ZygoteInit {
    	......
    
    	private static final String ANDROID_SOCKET_ENV = "ANDROID_SOCKET_zygote";
    		
    	......
    }
            那么,这个环境变量的值又是由谁来设置的呢?我们知道,系统启动脚本文件system/core/rootdir/init.rc是由init进程来解释执行的,而init进程的源代码位于system/core/init目录中,在init.c文件中,是由service_start函数来解释init.rc文件中的service命令的:

    void service_start(struct service *svc, const char *dynamic_args)
    {
    	......
    
    	pid_t pid;
    
    	......
    
    	pid = fork();
    
    	if (pid == 0) {
    		struct socketinfo *si;
    
    		......
    
    		for (si = svc->sockets; si; si = si->next) {
    			int socket_type = (
    				!strcmp(si->type, "stream") ? SOCK_STREAM :
    				(!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET));
    			int s = create_socket(si->name, socket_type,
    				si->perm, si->uid, si->gid);
    			if (s >= 0) {
    				publish_socket(si->name, s);
    			}
    		}
    
    		......
    	}
    
    	......
    }
            每一个service命令都会促使init进程调用fork函数来创建一个新的进程,在新的进程里面,会分析里面的socket选项,对于每一个socket选项,都会通过create_socket函数来在/dev/socket目录下创建一个文件,在这个场景中,这个文件便是zygote了,然后得到的文件描述符通过publish_socket函数写入到环境变量中去:

    static void publish_socket(const char *name, int fd)
    {
        char key[64] = ANDROID_SOCKET_ENV_PREFIX;
        char val[64];
    
        strlcpy(key + sizeof(ANDROID_SOCKET_ENV_PREFIX) - 1,
                name,
                sizeof(key) - sizeof(ANDROID_SOCKET_ENV_PREFIX));
        snprintf(val, sizeof(val), "%d", fd);
        add_environment(key, val);
    
        /* make sure we don't close-on-exec */
        fcntl(fd, F_SETFD, 0);
    }
    
           这里传进来的参数name值为"zygote",而ANDROID_SOCKET_ENV_PREFIX在system/core/include/cutils/sockets.h定义为:

    #define ANDROID_SOCKET_ENV_PREFIX	"ANDROID_SOCKET_"
    
            因此,这里就把上面得到的文件描述符写入到以"ANDROID_SOCKET_zygote"为key值的环境变量中。又因为上面的ZygoteInit.registerZygoteSocket函数与这里创建socket文件的create_socket函数是运行在同一个进程中,因此,上面的ZygoteInit.registerZygoteSocket函数可以直接使用这个文件描述符来创建一个Java层的LocalServerSocket对象。如果其它进程也需要打开这个/dev/socket/zygote文件来和Zygote进程进行通信,那就必须要通过文件名来连接这个LocalServerSocket了,参考 Android应用程序进程启动过程的源代码分析一文中的Step 4,ActivityManagerService是通过Process.start函数来创建一个新的进程的,而Process.start函数会首先通过Socket连接到Zygote进程中,最终由Zygote进程来完成创建新的应用程序进程,而Process类是通过openZygoteSocketIfNeeded函数来连接到Zygote进程中的Socket的:

    public class Process {  
    	......  
     
    	private static void openZygoteSocketIfNeeded()  
    			throws ZygoteStartFailedEx {  
    
    		......
    
    		for (int retry = 0  
    			; (sZygoteSocket == null) && (retry < (retryCount + 1))  
    			; retry++ ) {  
    
    				......
    
    				try {  
    					sZygoteSocket = new LocalSocket();  
    					sZygoteSocket.connect(new LocalSocketAddress(ZYGOTE_SOCKET,  
    						LocalSocketAddress.Namespace.RESERVED));  
    
    					sZygoteInputStream  
    						= new DataInputStream(sZygoteSocket.getInputStream());  
    
    					sZygoteWriter =  
    						new BufferedWriter(  
    						new OutputStreamWriter(  
    						sZygoteSocket.getOutputStream()),  
    						256);  
    
    					......  
    				} catch (IOException ex) {  
    					......  
    				}  
    		}  
    
    		......  
    	}  
    
    	......  
    }
            这里的ZYGOTE_SOCKET定义为:

    public class Process {  
    	......  
     
    	private static final String ZYGOTE_SOCKET = "zygote";  
    
    	......  
    } 
            它刚好就是对应/dev/socket目录下的zygote文件了。

            Android系统中的socket机制和binder机制一样,都是可以用来进行进程间通信,读者可以自己对比一下这两者的不同之处,Binder进程间通信机制可以参考Android进程间通信(IPC)机制Binder简要介绍和学习计划一文。

           Socket对象创建完成之后,回到Step 3中的ZygoteInit.main函数中,startSystemServer函数来启动SystemServer组件。

           Step 5. ZygoteInit.startSystemServer
           这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	private static boolean startSystemServer()
    			throws MethodAndArgsCaller, RuntimeException {
    		/* Hardcoded command line to start the system server */
    		String args[] = {
    			"--setuid=1000",
    			"--setgid=1000",
    			"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003",
    			"--capabilities=130104352,130104352",
    			"--runtime-init",
    			"--nice-name=system_server",
    			"com.android.server.SystemServer",
    		};
    		ZygoteConnection.Arguments parsedArgs = null;
    
    		int pid;
    
    		try {
    			parsedArgs = new ZygoteConnection.Arguments(args);
    
    			......
    
    			/* Request to fork the system server process */
    			pid = Zygote.forkSystemServer(
    				parsedArgs.uid, parsedArgs.gid,
    				parsedArgs.gids, debugFlags, null,
    				parsedArgs.permittedCapabilities,
    				parsedArgs.effectiveCapabilities);
    		} catch (IllegalArgumentException ex) {
    			......
    		}
    
    		/* For child process */
    		if (pid == 0) {
    			handleSystemServerProcess(parsedArgs);
    		}
    
    		return true;
    	}
    	
    	......
    }
            这里我们可以看到,Zygote进程通过Zygote.forkSystemServer函数来创建一个新的进程来启动SystemServer组件,返回值pid等0的地方就是新的进程要执行的路径,即新创建的进程会执行handleSystemServerProcess函数。

            Step 6. ZygoteInit.handleSystemServerProcess
            这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	private static void handleSystemServerProcess(
    			ZygoteConnection.Arguments parsedArgs)
    			throws ZygoteInit.MethodAndArgsCaller {
    		closeServerSocket();
    
    		/*
    		* Pass the remaining arguments to SystemServer.
    		* "--nice-name=system_server com.android.server.SystemServer"
    		*/
    		RuntimeInit.zygoteInit(parsedArgs.remainingArgs);
    		/* should never reach here */
    	}
    
    	......
    } 
            由于由Zygote进程创建的子进程会继承Zygote进程在前面Step 4中创建的Socket文件描述符,而这里的子进程又不会用到它,因此,这里就调用closeServerSocket函数来关闭它。这个函数接着调用RuntimeInit.zygoteInit函数来进一步执行启动SystemServer组件的操作。

            Step 7. RuntimeInit.zygoteInit

            这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

    public class RuntimeInit {  
    	......  
    
    	public static final void zygoteInit(String[] argv)  
    			throws ZygoteInit.MethodAndArgsCaller {  
    		......  
      
    		zygoteInitNative();  
    
    		......  
    
    
    		// Remaining arguments are passed to the start class's static main  
    
    		String startClass = argv[curArg++];  
    		String[] startArgs = new String[argv.length - curArg];  
    
    		System.arraycopy(argv, curArg, startArgs, 0, startArgs.length);  
    		invokeStaticMain(startClass, startArgs);  
    	}  
    
    	......  
    }
             这个函数会执行两个操作,一个是调用zygoteInitNative函数来执行一个Binder进程间通信机制的初始化工作,这个工作完成之后,这个进程中的Binder对象就可以方便地进行进程间通信了,另一个是调用上面Step 5传进来的com.android.server.SystemServer类的main函数。

             Step 8. RuntimeInit.zygoteInitNative

             这个函数定义在frameworks/base/core/java/com/android/internal/os/RuntimeInit.java文件中:

    public class RuntimeInit {  
    	......  
    
    	public static final native void zygoteInitNative();  
    
    	......  
    }
            这里可以看出,函数zygoteInitNative是一个Native函数,实现在frameworks/base/core/jni/AndroidRuntime.cpp文件中,这里我们就不再细看了,具体可以参考 Android应用程序进程启动过程的源代码分析一文的Step 9,完成这一步后,这个进程的Binder进程间通信机制基础设施就准备好了。

            回到Step 7中的RuntimeInit.zygoteInitNative函数,下一步它就要执行com.android.server.SystemServer类的main函数了。

            Step 9. SystemServer.main

            这个函数定义在frameworks/base/services/java/com/android/server/SystemServer.java文件中:

    public class SystemServer  
    {  
    	......  
    
    	native public static void init1(String[] args);  
    
    	......  
    
    	public static void main(String[] args) {  
    		......  
    
    		init1(args);  
    
    		......  
    	} 
    
    	public static final void init2() {  
    		Slog.i(TAG, "Entered the Android system server!");  
    		Thread thr = new ServerThread();  
    		thr.setName("android.server.ServerThread");  
    		thr.start();  
    	}  
    
    	......  
    }
            这里的main函数首先会执行JNI方法init1,然后init1会调用这里的init2函数,在init2函数里面,会创建一个ServerThread线程对象来执行一些系统关键服务的启动操作,例如我们在前面两篇文章 Android应用程序安装过程源代码分析Android系统默认Home应用程序(Launcher)的启动过程源代码分析中提到的PackageManagerService和ActivityManagerService。
            这一步的具体执行过程可以参考 Android应用程序安装过程源代码分析一文,这里就不再详述了。

            这里执行完成后,层层返回,最后回到上面的Step 3中的ZygoteInit.main函数中,接下来它就要调用runSelectLoopMode函数进入一个无限循环在前面Step 4中创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程了。

            Step 10. ZygoteInit.runSelectLoopMode

            这个函数定义在frameworks/base/core/java/com/android/internal/os/ZygoteInit.java文件中:

    public class ZygoteInit {
    	......
    
    	private static void runSelectLoopMode() throws MethodAndArgsCaller {
    		ArrayList<FileDescriptor> fds = new ArrayList();
    		ArrayList<ZygoteConnection> peers = new ArrayList();
    		FileDescriptor[] fdArray = new FileDescriptor[4];
    
    		fds.add(sServerSocket.getFileDescriptor());
    		peers.add(null);
    
    		int loopCount = GC_LOOP_COUNT;
    		while (true) {
    			int index;
    
    			......
    
    
    			try {
    				fdArray = fds.toArray(fdArray);
    				index = selectReadable(fdArray);
    			} catch (IOException ex) {
    				throw new RuntimeException("Error in select()", ex);
    			}
    
    			if (index < 0) {
    				throw new RuntimeException("Error in select()");
    			} else if (index == 0) {
    				ZygoteConnection newPeer = acceptCommandPeer();
    				peers.add(newPeer);
    				fds.add(newPeer.getFileDesciptor());
    			} else {
    				boolean done;
    				done = peers.get(index).runOnce();
    
    				if (done) {
    					peers.remove(index);
    					fds.remove(index);
    				}
    			}
    		}
    	}
    
    	......
    }      
            这个函数我们已经在 Android应用程序进程启动过程的源代码分析一文的Step 5中分析过了,这就是在等待ActivityManagerService来连接这个Socket,然后调用ZygoteConnection.runOnce函数来创建新的应用程序,有兴趣的读者可以参考 Android应用程序进程启动过程的源代码分析这篇文章,这里就不再详述了。

            这样,Zygote进程就启动完成了,学习到这里,我们终于都对Android系统中的进程有了一个深刻的认识了,这里总结一下:

            1. 系统启动时init进程会创建Zygote进程,Zygote进程负责后续Android应用程序框架层的其它进程的创建和启动工作。

            2. Zygote进程会首先创建一个SystemServer进程,SystemServer进程负责启动系统的关键服务,如包管理服务PackageManagerService和应用程序组件管理服务ActivityManagerService。

            3. 当我们需要启动一个Android应用程序时,ActivityManagerService会通过Socket进程间通信机制,通知Zygote进程为这个应用程序创建一个新的进程。

    老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注!

    展开全文
  • android系统进程简要分析

    千次阅读 2017-07-20 01:42:49
    android上利用ps aux命令打印出来的进程id与分析结果 USER PID PPID VSIZE RSS WCHAN PC NAME root 1 0 4532 1188 ep_poll 00004d549a S /init 盘古进程,其它用户进程的祖先进程 root 2 0 0 0 kthreadd ...
    在android上利用ps aux命令打印出来的进程id与分析结果
    WCHAN列的含义: 当前进程正在阻塞的内核函数名称和地址

    USER PID PPID VSIZE RSS WCHAN PC NAME
    root 1 0 4532 1188 ep_poll 00004d549a S /init 盘古进程,其它用户进程的祖先进程
    root 2 0 0 0 kthreadd 0000000000 S kthreadd 由idle进程创建,运行在内核空间,负责所有内核线程的调度和管理
    root 3 2 0 0 smpboot_th 0000000000 S ksoftirqd/0 监测软中断的内核线程
    root 4 2 0 0 worker_thr 0000000000 S kworker/0:0 第0个CPU的第0个工作进程
    root 5 2 0 0 worker_thr 0000000000 S kworker/0:0H 第0个cpu的第0H工作进程
    root 6 2 0 0 worker_thr 0000000000 S kworker/u4:0  u代表的是unbound,即未与CPU绑定的进程
    root 7 2 0 0 smpboot_th 0000000000 S migration/0 用于在不同的CPU间迁移
    root 8 2 0 0 rcu_gp_kth 0000000000 S rcu_preempt 读写更新 抢占器
    root 9 2 0 0 rcu_gp_kth 0000000000 S rcu_bh
    root 10 2 0 0 rcu_gp_kth 0000000000 S rcu_sched 读写更新  调度
    root 11 2 0 0 smpboot_th 0000000000 S migration/1 
    root 12 2 0 0 smpboot_th 0000000000 S ksoftirqd/1
    root 14 2 0 0 worker_thr 0000000000 S kworker/1:0H
    root 15 2 0 0 rescuer_th 0000000000 S khelper 用于调用内核模块的用户空间实现
    root 16 2 0 0 worker_thr 0000000000 S kworker/u4:1
    root 300 2 0 0 rescuer_th 0000000000 S writeback
    root 302 2 0 0 rescuer_th 0000000000 S bioset  block i/o管理
    root 304 2 0 0 rescuer_th 0000000000 S kblockd 用于卸载和影响ios延迟/吞吐率
    root 397 2 0 0 rescuer_th 0000000000 S ata_sff   ata是ide接口 sff是 2.5寸硬盘的意思
    root 408 2 0 0 hub_thread 0000000000 S khubd
    root 417 2 0 0 rescuer_th 0000000000 S md   Multiple Devices driver for Linux
    root 426 2 0 0 worker_thr 0000000000 S kworker/0:1
    root 427 2 0 0 rescuer_th 0000000000 S cfg80211  configure 802.11协议, 配置wifi的进程
    root 537 2 0 0 kswapd 0000000000 S kswapd0  内存管理中的页交换
    root 600 2 0 0 fsnotify_m 0000000000 S fsnotify_mark 文件系统通知标记进程
    root 620 2 0 0 rescuer_th 0000000000 S crypto  加密子进程
    root 640 2 0 0 worker_thr 0000000000 S kworker/1:1
    root 744 2 0 0 rescuer_th 0000000000 S iscsi_eh  SCSI是指一种硬件接口标准,与sata用在微型机上不同,一般出现在服务器(小型机)的硬盘上,性能高,安卓很明显没有这种接口,为什么有启动这个进程呢?
    root 758 2 0 0 scsi_error 0000000000 S scsi_eh_0  创建一个scsi_eh进程,这进程在ubuntu上也存在
    root 761 2 0 0 scsi_error 0000000000 S scsi_eh_1
    root 775 2 0 0 worker_thr 0000000000 S kworker/1:2
    root 800 2 0 0 rescuer_th 0000000000 S uether  不知何用,在ubuntu进程上不存在
    root 818 2 0 0 rescuer_th 0000000000 S dm_bufio_cache  dm是指 RAID and LVM drivers 缓冲io
    root 849 2 0 0 rescuer_th 0000000000 S binder 大名鼎鼎的binder进程,android进程间通信的核心
    root 868 2 0 0 rescuer_th 0000000000 S deferwq defer work queue  开启延迟设备检测
    root 881 1 4272 744 poll_sched 00004bfb8a S /sbin/ueventd  事件后台进程
    root 1189 2 0 0 worker_thr 0000000000 S kworker/1:1H
    root 1190 2 0 0 kjournald2 0000000000 S jbd2/vda-8  journal block device2   vda-8是设备名称
    root 1191 2 0 0 rescuer_th 0000000000 S ext4-dio-unwrit  ext4文件系统相关进程
    root 1192 2 0 0 worker_thr 0000000000 S kworker/0:1H
    root 1193 2 0 0 kjournald2 0000000000 S jbd2/vdb-8    journal block device2   vdb-8是设备名称
    root 1194 2 0 0 rescuer_th 0000000000 S ext4-dio-unwrit
    root 1198 2 0 0 kjournald2 0000000000 S jbd2/vdc-8     journal block device2   vdc-8是设备名称
    root 1199 2 0 0 rescuer_th 0000000000 S ext4-dio-unwrit
    紫色是由init进程创建出来的进程 一共有21个进程 这些进程都是在system/core/rootdir/init.rc中配置的
    logd 1200 1 14452 3428 sigsuspend 7ff9f0a198a7 S /system/bin/logd 日志进程
    root 1201 1 14424 3340 hrtimer_na 7fb867a8c2a7 S /system/bin/vold volume daemon volume是外部存储设备的意思
    root 1204 1 4364 532 ep_poll 000044e01a S /sbin/healthd  安卓特有的 健康(电池)管理进程
    root 1205 1 5972 1384 ep_poll 7f0535a6636a S /system/bin/lmkd  lowmemorykillerdaemon 低内存杀手
    system 1206 1 5920 1528 binder_thr 7efefcbb5607 S /system/bin/servicemanager  binder服务的订阅查询服务进程
    system 1207 1 58212 4436 ep_poll 7f51015cd36a S /system/bin/surfaceflinger  与ui有关的进程
    root 1213 2 0 0 kauditd_th 0000000000 S kauditd  内核审核守护进程
    shell 1216 1 6108 1604 n_tty_read 7fcfcab6da27 S /system/bin/sh  从init进程派生一个shell进程出来?
    root 1217 1 12116 436 poll_sched 0000445daa S /sbin/adbd    adb后台进程
    root 1219 1 18392 2476 hrtimer_na 7fd18ecdf2a7 S /system/bin/netd  网络相关进程
    root 1220 1 4168 1152 __skb_recv 00f7543343 S /system/bin/debuggerd  调试器
    root 1221 1 6064 1348 __skb_recv 7f7010619bea S /system/bin/debuggerd64
    radio 1222 1 11212 1984 hrtimer_na 7f0791d462a7 S /system/bin/rild    radio interface layer daemon 通信层后台
    drm 1223 1 16484 3972 binder_thr 00f73aaa06 S /system/bin/drmserver 数字版权管理进程
    media 1224 1 134920 10000 binder_thr 00f6f4da06 S /system/bin/mediaserver
    root 1225 1 5764 1324 unix_strea 7f0f5585aa27 S /system/bin/installd  负责安装应用程序的进程
    keystore 1229 1 9824 2656 binder_thr 7f9be1356607 S /system/bin/keystore 证书管理
    root 1230 1 1264956 63756 poll_sched 7f2296d6ab4a S zygote64 //这是第一个客户进程,server_server进程和zygote64进程通信以创建其它的app进程
    root 1231 1 1253588 53328 poll_sched 00f7323270 S zygote  它好像没用
    system 1236 1 9240 2352 binder_thr 7fb476a27607 S /system/bin/gatekeeperd  锁屏幕处理进程
    root 1239 1 5780 1352 hrtimer_na 7f26315342a7 S /system/xbin/perfprofd   perf profile collection daemon 性能搜集进程
    system 1240 1 10248 2552 binder_thr 7fe325dfd607 S /system/bin/fingerprintd  指纹进程
    system 1573 1230 1410504 91100 ep_poll 7f2296d6a36a S system_server  大名鼎鼎的system_server进程,ams,pms等服务都运行在这个进程
    media_rw 1656 1201 9440 2016 inotify_re 7f75425a6a27 S /system/bin/sdcard 它由vold进程创建的
    u0_a14 1687 1230 1337636 86544 ep_poll 7f2296d6a36a S com.android.systemui  系统状态栏进程
    media_rw 1734 1201 9440 2016 inotify_re 7fa299b93a27 S /system/bin/sdcard  它由vold进程创建的,不明白为什么会创建2个sdcard进程
    u0_a33 1888 1230 1284376 43328 ep_poll 7f2296d6a36a S com.android.inputmethod.latin 输入法进程
    u0_a6 1903 1230 1277164 39824 ep_poll 7f2296d6a36a S android.process.media 媒体进程
    radio 1912 1230 1298720 51496 ep_poll 7f2296d6a36a S com.android.phone  telephony通话服务进程 是一个app
    u0_a3 1984 1230 1283044 45560 ep_poll 7f2296d6a36a S android.process.acore   contactsprovider进程
    u0_a24 2129 1230 1278068 35972 ep_poll 7f2296d6a36a S com.android.deskclock  闹钟进程
    u0_a43 2145 1230 1272576 31620 ep_poll 7f2296d6a36a S com.android.quicksearchbox   快速搜索框进程
    system 2159 1230 1286404 31796 ep_poll 7f2296d6a36a S com.android.settings   设置进程
    u0_a20 2185 1230 1281032 34544 ep_poll 7f2296d6a36a S com.android.calendar   日历进程 packages/apps/Calendar
    u0_a1 2204 1230 1274268 35960 ep_poll 7f2296d6a36a S com.android.providers.calendar   日历提供器进程packages/providers/CalendarProvider
    u0_a8 2297 1230 1310228 63772 ep_poll 7f2296d6a36a S com.android.launcher3   启动器进程,即桌面
    u0_a28 2326 1230 1290128 39684 ep_poll 7f2296d6a36a S com.android.email  邮件服务进程
    u0_a46 2368 1230 1287232 46820 ep_poll 7f2296d6a36a S com.android.messaging 短消息进程
    root 3054 1217 6108 1672 sigsuspend 7faf6f0918a7 S /system/bin/sh  shell终端进程
    root 3058 3054 5780 1304 0 7fcd6aa76a27 R ps 显示这个信息的ps进程


    存在分析不完善和错误欢迎交流!
    展开全文
  • 想在android系统层写两个可执行程序(main_a,main_b),使用ndk-build编译。 main_a 用来录音,main_b通过进程件套通信方式从main_a中把录音数据接收过来保存成文件。对于android来说,能想到的进程间通信方式是mmap...
  • 在前面一篇文章浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路中,介绍了Service Manager是如何成为Binder机制的守护进程的。既然作为守护进程,Service Manager的职责当然就是为Server和...
  • Android系统中如何获取系统进程信息
  • 本文是进程管理系统文章的第一篇,会讲解Android系统中的进程创建。本文适合Android平台的应用程序开发者,也适合对于Android系统内部实现感兴趣的读者。Android系统以Linux内核为基础,所以对于进程的管理自然离不...
  • Android系统进程分析

    2017-03-27 13:41:29
    最近太忙了,但是我也没有放下学习的步伐,这次的内容有点多,主要介绍了Android系统中的进程: Zygote进程; System进程; 应用程序进程。 再此说句题外话,本来想模仿写一些那些大V写得博客那样犀利言语,精彩片段...
  • Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,因为Android系统是基于Linux内核的,而在Linux系统中,所有的进程都是init进程的子孙进程,也就是说,所有的...
  • Android系统zygote进程初始化过程
  • Android系统进程分类

    2015-04-04 22:33:41
    2、可见进程:一般还是显示在屏幕中,但是用户并没有直接与之进行交互,该进程对用户来说同样是非常重要的进程,除非为了保证前台进程的正常运行,否则Android系统一般是不会将该进程终止的。 3、服务进程:便是...
  • 在上一篇博文《Android之——杀死用户选中的进程优化》一文中,我向大家介绍了如何优化用户的体验,那么这篇博文中,我将向大家介绍如何进行系统进程与用户进程的分离操作。同样,这篇博文是基于上一篇博文改进的。...
  • 本文是Android系统进程管理的第三篇文章。进程管理的前面两篇文章,请参见这里: Android系统中的进程管理:进程的创建Android系统中的进程管理:进程的优先级 本文适合Android平台的应用程序开发者,也适合...
  • 本文是Android进程管理系列文章的第二篇,会讲解进程管理中的优先级管理。 进程管理的第一篇文章:《进程的创建》请跳转至...在Android系统中,进程的优先级影响着以下三个因素: 当内存紧张时,系统对于进程
  • Android系统启动流程—— init进程zygote进程SystemServer进程启动流程.pdf
  • 一、linux进程间通讯实现方式有很多种。包含管道、信号、共享内存、套接字 而 管道、信号、共享内存 这三种方式只适用于同一台设备间进程间通讯。套接字可以跨设备进行进程间通讯 1.管道机制 管道机制是...
  • Android 系统开发中经常需要通过属性在各个进程间传递信息,通过一个进程 set_property,另一个进程 get_property 达到进程间通信的需求。 属性获取没有限制,但是如果需要进程可以进行设置属性操作,则需要做一些...
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 (Visible process) 服务进程 ...
  • android系统启动 recovery升级模式:启动recovery分区内核和文件系统 正常启动模式: 引导内核和启动Android系统 android系统由uboot启动: 1、输入模式,输入了recover命令,重启uboot就会引导recover分区, ...
  • Android系统启动完成之后,我们安装的应用程序又是如何启动的呢?启动一个应用程序首先要保证该应用程序的进程已经被启动,本篇文章我们就基于Android8.1系统来分析应用程序进程启动过程。需要注意,是“应用程序...
  • Android 系统(243)---Android进程系列第一篇---进程基础.pdf
  • Android进程保活·设置前台Service,提升App进程优先级 Android进程 此文章代码Github上有提交: 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 ...
  • Init进程在初始化过程中会启动很多重要的守护进程,因此,了解Init进程的启动过程有助于我们更好的理解Android系统。 在介绍Init进程前,我们先简单介绍下Android的启动过程。从系统角度看,Android的启动过程可分为...
  • Android进程保活 Android进程 首先你要知道Android中的进程以及它的优先级,下面来说明它进程 前台进程 (Foreground process) 可见进程 (Visible process) 服务进程 (Service process) 后台进程 (Background ...
  • Android系统查看某个进程的线程

    千次阅读 2019-07-23 20:40:51
    Android系统中的应用通常对应一个或多个进程进程内部会创建并执行多个线程,那我们如何监控其中单个线程的状态和详细情况呢?(如,CPU/内存使用率)。 Android系统本身是基于Linux系统的,所以Linux系统的查看...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 184,153
精华内容 73,661
关键字:

安卓系统进程