javasocket客户端端口号(java socket客户端代码)

太平洋在线手机版 25 0

  本文来自于CSDN博客,作者:天堂1223,已获授权,版权归原作者所有,未经作者同意,请勿转载。

  欢迎同有博客好文章的作者加微信(ID:tm_forever_miss)或直接邮件(mobilehub@csdn.net)投稿、约稿、给文章纠错。

  在这篇文章中,我们将从代码角度仔细学习Android系统的启动过程,同时,学习Android启动过程中的初始化脚本语言,即init.rc中的语言语法。在这里,不在详细介绍Linux内核的启动过程,主要学习从Linux内核启动之后,init初始化是如何工作的,他是如何启动Android系统的第一个进程–Zygote进程。并且还会继续了解后面其他的进程是如何通过Zygote进程启动的。话不多说,我们现在就来学习Android系统启动之路。

  Android系统启动流程图

  我们都知道,Android系统内核是基于Linux内核,所以在Android系统启动过程中,首先启动Linux内核,Bootloader加载并启动Linux内核,内核启动完成之后,内核开始启动Android系统的init进程,然后init进程通过init.rc启动脚本语言的执行,来启动Zygote进程,作为Android其他进程的父进程,Zygote进程做完初始化工作之后,启动SystemServer来启动其他系统服务。

  下面我们从init进程的启动开始学习。

  该文件位于system/core/init/init.cpp中,我们来看看init进程都做了哪些工作。

  首先,init进程添加环境变量,并且挂载相应的目录。在主目录/之外为kmsg和null创建设备节点。初始化selinux,由于我们这里并不研究selinux的运行机制,所以其初始化细节也不在详究。根据起注释可以知道,如果当前系统处于内核域中,重新执行init来转换到init域中,因为SELinux策略已经被加载了。下面接着通过restorecon命令来将在selinux启动之前创建的目录的安全上下文恢复到正确的属性。

javasocket客户端端口号(java socket客户端代码)-第1张图片-太平洋在线下载

  接着,便是信号处理机制的初始化工作,加载启动属性,并启动属性服务器。下面,便进入至关重要的一个函数,也是init进程的主要工作,便是执行init_parse_config_file("/init.rc")函数,该函数的主要作用就是解析init.rc文件,并执行init初始化进程语言。下面我们来看一下这个函数:

  该代码位于system/core/init/init_parser.cpp中,该函数读取init.rc文件,并将数据传入到parse_config(path, data)函数中。

  我们来看一下parse_config函数:

  该函数和刚刚那个函数位于同一个文件中,很明显,该函数用于解析读取的init.rc文件的字符串,该函数与文件parse.cpp中的next_token()函数配合,进行字符串的解析,然后通过调用parse_new_section()函数将services和actions等添加到运行队列中,等待trigger触发器的触发运行。

  有关与Android init language(Android初始化语言)我在博客 Android Init Language(android初始化语言)中已经进行了详细的介绍。下面我们接着看init进程中的main函数中所做的工作:

  init.rc解析完成之后,所有的启动项目都被放入到action_add_queue_tail中,接着调用action_for_each_trigger("early-init", action_add_queue_tail),触发early-init触发器来出发这些相关services和actions的运行。

  我们来看一下,在init.rc中,我们看early-init相关启动的services和actions。在这里基本上是恢复某些文件或文件夹的安全上下文,然后调用init_zygote32_64.rc文件中的命令启动zygote。

  这里的意思是通过/system/bin/app_process32程序启动zygote进程,参数为--zygote和--start-system-server,这两个参数在后面我们会用到的。下面我们来看一下Zygote的main函数。

  该代码位于frameworks/base/core/Java/com/android/internal/os/ZygiteInit.java中。在代码中,他首先通过参数判断是否启动systemServer,也就是通过刚刚我们记录下来的参数--start-system-server判定startSystemServer为true;接着通过调用registerZygoteSocket(socketName)函数来注册zygote套接字,进行进程间的通信,我们来看一下这个函数:

  该代码位于同一个文件中,通过代码我们可以看到,创建zygote套接字的方式是通过创建一个LocalServerSocket对象来建立进程间的通信,在注释中有说明,注册一个服务套接字用于zygote命令连接。

  创建完成zygote套接字之后,执行preload()函数来进行资源文件的预加载工作。

  在这里,加载类,加载资源文件,加载OPenGl,加载共享库,文本资源以及准备WebView。这里不在所说,我们接着往下看。

  接着便调用startSystemServer(abiList, socketName)方法启动系统服务,我们来看一下这个函数:

  在这里准备系统服启动的参数,并通过forkSystemServer来创建系统服务进程,接着调用handleSystemServerProcess(parsedArgs)来进行系统服务的处理。

  在这里完成对创建的系统服务剩余的工作,最后调用RuntimeInit.zygoteInit将剩余的参数传递到系统服务中。

  该函数位于同目录下面的RuntimeInit.java文件中。这里的nativeZygoteInit()用于进程间通信的初始化操作,applicationInit函数用于服务的启动,我们来看一下:

  该函数主要是一些运行时的一些工作,同时调用invokeStaticMain来进行main函数的执行,看这个方法的注释,意思便是剩下的参数被传递,用于启动类的静态main函数。这里传递的类参数便是SystemServer类,所以这个函数的工作便是启动SystemServer的main函数。

  该函数位于frameworks/base/services/java/com/android/server/SystemServer.java类中,这里运行SystemServer的run函数,该函数设置环境变量,启动其他服务,后面就不再赘述了。

javasocket客户端端口号(java socket客户端代码)-第2张图片-太平洋在线下载

  接着返回到ZygoteInit.java的main函数中,这个函数最后执行runSelectLoop函数,这里运行一个循环,接收新的连接,读取来自连接的命令。

  至此,Android系统的启动过程就到了启动系统服务以及其他服务阶段了,后面我们会在别的博客中进行学习和讲解。

  了解最新移动开发、VR/AR 干货技术分享,请关注 mobilehub 微信公众号(ID: mobilehub)。

标签: javasocket客户端端口号

抱歉,评论功能暂时关闭!