windows phone 程序是如何启动的了,他和android程序有什么区别,我们重点从native code 层面来分析

在windows phone 程序启动的时候是:

在XAML中使用应用程序定义指定起始Page(它是启动 WindowsPhone7程序时自动加载的Page)。
  指定方法是将 StartupUri 属性设置为所需的 Page 的 统一资源标识符 (URI)。
  可以在标记中以声明方式设置 StartupUri,如下面的示例所示。
<Application
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SDKSample.App"
    StartupUri="PageWithHyperlink.xaml" />
  此例中,StartupUri 特性设置为标识 HomePage.xaml 的相对 pack URI。当WindowsPhone7 APP 启动时,将自动导航到 HomePage.xaml 并显示该文件。就是这个鸟样:

至于android是如何启动的,我这里要从native code 讲起来。

首先,大家都知道android是linux内核的,他的启动自然离不开linux中的boothloader与kernel启动,这里面我就不做过多的赘述。

下面都是android的从servicemanager里面来启动相应的后台进程,用zyngote来启动daemon process。这个后台进程是用来使其程序得以维持,而daemon 这个守护进程是对程序的状况得以监听的。至于daemon process 在java上的应用确实很多,譬如用apache 发布jsp的程序的时候,这个apache就是守护进程。

servicemanager这是c语言中定义,定义中的后台的进程,至于zynote这个进程了,这是从app_main cp中来开启一个initial方法对其初始化方法。

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

接下来的socket关键字表示这个zygote进程需要一个名称为"zygote"的socket资源,这样,系统启动后,我们就可以在/dev/socket目录下看到有一个名为zygote的文件。这里定义的socket的类型为unix domain socket,它是用来作本地进程间通信用的,具--基于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进程启动的过程之前,我们先来看看它的启动序列图:

这是app_ain中的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;  }  }  

我们惊奇的看到了start了zynote.cs 文件,   这个就是开启了zynote进程,这个就是当前守护进程的初始化。那么这个zynote.cpp是什么了?
我们看其中AndroidRuntime的源代码:

  1. ......
  2. static AndroidRuntime* gCurRuntime = NULL;
  3. ......
  4. AndroidRuntime::AndroidRuntime()
  5. {
  6. ......
  7. assert(gCurRuntime == NULL);        // one per process
  8. gCurRuntime = this;
  9. }

这个androidRunTime,是cpp文件, 是通过jnt方式用java来访问c++的源代码,这是android能够调用linux kernel中的关键性的技术。

这就是我对android 中的启动理解。

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

它主要作了三件事情,一个调用registerZygoteSocket函数创建了一个socket接口,用来和ActivityManagerService通讯,二是调用startSystemServer函数来启动SystemServer组件,三是调用runSelectLoopMode函数进入一个无限循环在前面创建的socket接口上等待ActivityManagerService请求创建新的应用程序进程。

这个socket接口是通过文件描述符来创建的,这个文件描符代表的就是我们前面说的/dev/socket/zygote文件了。这个文件描述符是通过环境变量ANDROID_SOCKET_ENV得到的,它定义为:

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

每一个service命令都会促使init进程调用fork函数来创建一个新的进程,在新的进程里面,会分析里面的socket选项,对于每一个socket选项,都会通过create_socket函数来在/dev/socket目录下创建一个文件,在这个场景中,这个文件便是zygote了,然后得到的文件描述符通过publish_socket函数写入到环境变量中去:

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

这是我对android理解,这能够对大家带来帮助。

好好学习,天天向上。

比较windows phone程序启动和android程序启动原理相关推荐

  1. java 切换后台程序_将 Android 程序切换到后台及从后台切换到前台实现

    将 Android 程序切换到后台及从后台切换到前台实现 有时候, 我们需要将自己的 Android 程序切换到后台运行, 在必要时, 将其切换到前台运行下面提供了一种实现方式, 首先需要引用三个单元 ...

  2. android启动分析,Android APP启动方式、启动流程及启动优化分析

    本文章向大家介绍Android app应用启动的一些相关知识,包括app启动方式.app启动流程和app启动优化等知识! app应用启动方式 1.冷启动 当启动应用时,后台没有该应用的进程,这时系统会 ...

  3. android zygote启动流程,Android zygote启动流程详解

    对zygote的理解 在Android系统中,zygote是一个native进程,是所有应用进程的父进程.而zygote则是Linux系统用户空间的第一个进程--init进程,通过fork的方式创建并 ...

  4. 用adb命令启动停止Android程序

    开启apk应用 adb shell am start -n breakan.test/breakan.test.TestActivity 其中"breakan.test/breakan.te ...

  5. android launcher启动过程,Android应用启动过程-Launcher源码浅析

    本文参考的源码(7.1.1_r6) Launcher也是一个应用程序,和我们的App没有什么区别,当用户点击应用图标时候,启动其他的App,本文主要为分析Activity的启动流程打基础. Launc ...

  6. Android8.0 开机启动脚本,Android开机启动shell脚本(Android 8.0测试OK)

    Android 下做开机启动shell脚本的大致流程如下: 目录 写shell脚本 为脚本写te文件 在init.rc中启动脚本 添加Selinux权限 写shell脚本 比如新建一个init.tes ...

  7. android 启动蓝牙设备,Android 蓝牙启动过程

    到网上摘抄的,来自 蓝牙设置种常用的Intent,下面是在bluetoothsettings.java 中注册蓝牙Intent的函数: private boolean initBluetoothAPI ...

  8. android 服务开机启动慢,Android App启动慢原因

    一.App启动方式: 冷启动(Cold Start).温启动(Warm start).热启动(Hot start) 1.  冷启动(Cold Start):是指App启动后第一次运行,获取App进程杀 ...

  9. app卡在启动页面android,app启动一直停留在启动页面

    环境: xcode:9.2 ios:ios12.0 iphone6sp 问题描述:真机调试时 app打开后一直停留在启动页面不进入页面跳转: 打印日志: objc[7637]: Class MPReq ...

最新文章

  1. 使用基本的socket函数
  2. ABAP之程序相互调用--SUBMIT
  3. VTK:小部件之CompassWidget
  4. 处理字符串_1_生成自增值
  5. python3 idle自动补全_给Python IDLE加上自动补全和历史功能
  6. 回文数Python解法
  7. WIFI无线路由器的五种工作模式
  8. 分析器错误信息: 未能加载类型命名空间.类... ---小结
  9. python scrapy框架 抓取的图片路径打不开图片_Python中Scrapy爬虫图片处理详解
  10. 乐源机器人没电提醒吗_云迹讲解机器人,你的专属机器人服务专家
  11. 联想计算机怎么设置硬盘,联想电脑硬盘模式怎么更改
  12. O-RAN专题系列-41:管理面-WG4.MP.V07-规范解读-第8章-故障管理FM
  13. Y件DOOK: VSC 安装 谷歌浏览器调试 固件插件 Debugger for Chorme
  14. Verilog学习笔记HDLBits——Shift Registers
  15. Java代码给csv文件加水印_如何给文件加上水印?
  16. 友元函数,友元类,类模板
  17. 【历史上的今天】1 月 15 日:维基百科上线;信息安全大师出生;英特尔推出 Viiv
  18. 不定代词all/any/none的区别
  19. NLP竞赛全球亚军,我的科研经验分享
  20. 软件测试2020年终总结

热门文章

  1. [WCF]配置文件中Certificate 的encodeValue怎么设置?
  2. EF架构~为EF DbContext生成的实体添加注释(T4模板应用)
  3. MyBatis MapperScannerConfigurer配置——MyBatis学习笔记之八
  4. 加码IoT生态圈:爱立信携手客户及合作伙伴共筑物联网之梦
  5. SpringMvc-Httl-shiro的整合
  6. OAF_EO系列2 - Validation数据校验验证机制(概念)
  7. 一款小巧好用的MAC地址扫描器
  8. Linux查找文件 —— whereis 、 find、 locate、 which
  9. mysql 更新多条id键值相同记录中的最新(最后一条)记录
  10. WebRequest 请求被中止: 请求已被取消。 错误解决方法