比较windows phone程序启动和android程序启动原理
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:
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, ", 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的源代码:
这个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编译FFmpeg for Android 和AndroidStudio使用FFmpeg(二) FFmpeg的编译是一个大坑,尤其是编译安卓平台的动态库和静态库,应用于APP中。在Linux平台编译是相对简单的,但是我经过尝试在Linux编译静态库没有成功,所以又在windows平台尝试编译了ffempg的动态库,应用成功了,这里分享一下。
windows编译FFmpeg for Android 和AndroidStudio使用FFmpeg(一) FFmpeg的编译是一个大坑,尤其是编译安卓平台的动态库和静态库,应用于APP中。在Linux平台编译是相对简单的,但是我经过尝试在Linux编译静态库没有成功,所以又在windows平台尝试编译了ffempg的动态库,应用成功了,这里分享一下。
[20180319]windows批处理文件大小比较.txt [20180319]windows批处理文件大小比较.txt --//我使用eDiary写日志,有时候为了安全期间,我在U盘保留一份备份. --//需要同步,但是eDiary有一个 问题 就是如果打开日记本,没有任何操作,都会修改文件的时间戳.
相关文章
- [Android Pro] android控件ListView顶部或者底部也显示分割线
- [Android Pro] android root权限破解分析
- Android教程-android studio 制作.9 图片
- Android开发之旅: Intents和Intent Filters(理论部分)
- 《android开发艺术探索》读书笔记(十五)--Android性能优化
- EasyPlayer-RTSP播放器:从底层到上层专注于RTSP播放Windows、Android、iOS RTSP Player
- Android 自定义dialogfragment
- Android版OpenCV图像处理技术亲自验证[十五]之Tutorial Features点检测
- Android问题笔记 -关于Kotlin插件版本的问题
- Android 拷贝SQLite数据库文件到手机的内部存储
- windows server 2008 安装Microsoft ActiveSync 6.1提示缺少一个Windows Mobile设备中心所须要的Windows组件
- 【Android Gradle 插件】Module 目录下 build.gradle 配置文件 ( android 闭包块配置 | AppExtension 扩展类型参考文档 )
- 【错误记录】Windows 控制台程序编译报错 ( WINDOWS.H already included. MFC apps must not #include <Windows.h> )
- Windows在生产体系Android开关机动画
- 【Android布局】在程序中设置android:gravity 和 android:layout_Gravity属性
- android 输入法如何启动流程_Android输入法显示流程
- 【Android入门】3、UI 控件:TextView、Button、ImageView、AlertDialog 和 LinearLayout、RelativeView、ListView 布局
- android开发,Android Studio Build Output 输出的中文显示乱码