1. 我们做了个什么东西?

提供了一个Android模拟器,运行流畅度可以类比真机,可以正常运行市面上的大部分应用,比如应用宝,手机管家等。在功能性测试的场景下,比真机节约成本,维护更方便。

2. 原生安卓模拟器的缺点?

说Android模拟器慢其实是指早期Google提供的只能用于在Arm架构上运行的Android镜像在模拟器上运行慢。与此对照的是,iOS模拟器运行非常流畅。其实,iOS提供的叫 Simulator(模拟器),Android提供的叫Emulator(仿真器)。

事实上 iOS Simulator 仅仅是 API 级别的模拟,并不是完整的运行了一个系统,可以说 iOS Simulator 就是一个特殊的软件,通过一定的 IPC 机制实现的一个高度模拟 iOS 的 Mac app。可以作为验证的是,iOS Simulator上只是能够运行在x86环境下编译的非签名程序(Developer Account),并不能安装发布到App Store上的只提供了针对ARM指令集的签名程序。

而 Android Emulator,是提供了虚拟机。从硬件(主要指 CPU 架构)到软件(完整 Linux 内核和 ROM)在原理上完全拟真。

对于ARM 版的Android镜像在Emulator上运行,需要Emulator模拟出一个arm的处理器,可以想象,系统本来是针对ARM指令集的,所有的指令都需要虚拟机模拟出来的arm处理器执来执行,效率必然打了很大折扣,所以就慢了。

后来,Google提供了x86版本的Android镜像,这时候就不用模拟异构处理器了,也就不用去做动态指令集翻译的活了,借助KVM(linux内核模块,属于硬件虚拟化技术,负责借助于硬件VT加速特性实现虚拟机的CPU虚拟化,内存虚拟化等),运行速度就大大加快了,在主机性能良好的情况下,Emulator流程程度甚至比真机还要好。但是,实际使用的话,会发现市面上大部分应用是安装不进去的。

因为习惯上都叫Android模拟器,所以后面描述里的Emulator、模拟器、仿真器不再区分,都是指Android Emulator。

2.  模拟器的启动流程?

AS提供了AVD Manager可以可视化的管理模拟器的创建创建和启动。

创建过程里需要指定使用的Android镜像(分arm版和x86版),选择arm版时AS会提示选择x86版本能提高10倍的性能。还可以设定分辨率、数据分区大小等。这些设定会创建一个config.ini的配置文件和设定大小的userdata.img、sdcard.img。config.ini里配置了系统镜像的路径system.img.

查看下载的镜像文件夹,除了system.img, 还有一个很重要的文件ramdisk.img, ramdisk是根文件系统,包含一些对于启动android很重要的文件,比如内核启动完后加载的第一个进程init、一些重要的配置文件等,总之它控制着整个android的启动。根据 init.rc, init.ranchu.rc来初始化并装载系统库、程序等直到开机完成。system.img会挂载到/system目录下。userdata.img是用来存放用户数据的,会被挂载到/data目录下,实际在虚拟机运行时,生成使用的是userdata-qemu.img,可读写。当在模拟器上安装和运行应用时,就是在/data目录下复制和产生了文件,所以设定的userdata.img不能太小,userdata.img大小可以直接认为等同真机的ROM大小。

创建avd界面

生成的avd目录

Avd的config.ini文件内容

得到avd之后可以通过命令行的方式启动:

emulator -avd AVD_NAME -verbose, 加verbose查看日志。

通过日志可以看出内部调用的是qemu-system-i386

查看emulator/qemu目录可以看到这里有qemu-system-armel等多个文件,分别对应不同的架构,调用哪个取决于AVD里设置的target-arch, 我们创建的模拟器target-arch是x86, 所以调用的就是qemu-system-i386。

TMOS中使用的avd是通过脚本的方式生成这些文件来实现创建的。需要注意的是,一个AVD代表一个模拟器实例,只能启动一次。

4. Android Emulator是怎么实现的?

通过前面的emulator启动过程日志可以看出,emulator命令后负责启动虚拟机的是qemu-system-i386。实际上Android Emulator就是基于QEMU改写的,Virtual Box也是在QEMU基础上改写的。Android Emulator在QEMU基础上增加了telephony、gps等。

QEMU是Linux上著名的开源模拟器,能够模拟出不同架构的处理器、硬盘和网卡等。效率上,当模拟的是同构处理器时,借助于KVM能够达到接近主机的性能。Qemu里已经集成了kvm, ubuntu上直接安装qemu-kvm。KVM依赖于硬件的虚拟化支持,所以需要在BIOS上开启VT。

KVM (Kernel-based Virtual Machine) is a FreeBSD and Linux kernel module that allows a user space program access to the hardware virtualization features of various processors, with which QEMU is able to offer virtualization for x86, PowerPC, and S/390 guests. When the target architecture is the same as the host architecture, QEMU can make use of KVM particular features, such as acceleration.

5. 怎么实现在x86模拟器上运行只提供了arm 库文件的应用?

Java虚拟机屏蔽了底层处理器的差异,所以对于只有Java代码的apk来说可以充分享受x86模拟器带来的流畅运行速度。

但是很多APK使用了JNI,调用了C语言编写的模块,虽然使用Google提供的NDK工具可以非常方便的生成分别针对x86/arm/MIPS等架构的的库文件,但大部分应用只提供了针对ARM编译的so库,这样的apk在x86的处理器上就无法运行了。

安装应用时,PMS会检查ro.product.cpu.abilist和ro.product.cpu.abilist32的值,x86镜像里这两个值都是x86,表明本系统只有执行x86指令集的能力,这样如果APK里只有针对ARM指令集的动态库,那安装就无法通过,提示ABI不支持。把这两个属性值改为x86,armeabi-v7a,armeabi 标识本系统能支持这些指令集,就能骗过PMS,使应用正常安装。但应用此时并不能运行。

为了解决Atom x86处理器上运行Android系统的问题,Intel提供了一个叫做houdini的模块,提供了动态转换指令集的能力,使得x86 Android系统能够执行针对arm指令集的so库文件。Android5.0后在系统层面提供了NativeBridge,支持接入这样的转换器,所以5.0后要把houdini模块添加到系统里是比较简单的。但Houdini是闭源的,不对外提供使用文档。需要的二进制文件可以从x86 Android官网获取或者从Genymotion获取。集成方法也可以参照这两个实现进行。

系统默认启动是不开启NativeBridge能力的,打开需要把ramdisk.img里的ro.dalvik.vm.native.bridge=0注释。系统启动后,又会读取ro.dalvik.vm.native.bridge的值,默认为0,表示不开启,改为为libhoudini.so, 则会使用libhoudi.so提供的能力进行动态指令集的转换。

6. 怎么增加Wifi连接?

原始SDK里的Android镜像启动后是以mobile的方式联网的,无法打开WiFi联网。系统里已经包含了正常开启Wifi需要的Framework部分,但缺少硬件的模拟、HAL的支持以及相关的库和可执行文件。

(外源)

qemu 命令支持增加虚拟网卡参数,模拟出硬件层支持。

增加HAL层的libhardware_legacy.so提供对硬件的操作。

通过wpa_supplicant-ieth1 -Dwired -c/data/misc/wifi/wpa_supplicant.conf 命令来启动守护进程wpa_supplicant, 提供了wpa_server, 配置文件wpa_supplicant.conf提供wifi热点.                          wpa_cli命令则实现连接热点。具体实现由libwpa_client.so提供。

默认系统启动时是不连接WiFi的,可以通过adb shell svc wifi enable连接到wifi。svc命令内部是通过调用WifiManager.enable实现的。启动过程中,观察logcat,可以看到wpa_supplicant服务的启动。

7. 怎么实现远程观看界面?

qemu提供了VNC Server的实现,可以通过-qemu -vnc :2打开。然后可以用任何实现了VNC协议的客户端连接到虚拟机上,实现远程控制。

VNC (Virtual Network Computing)是虚拟网络计算机的缩写。 VNC是把被控制端的屏幕做成图像,经过压缩后传送到控制端,控制端的控制信息(如鼠标信息)传送到被控制端后进入消息队列。这样就实现了远程控制服务端机器的能力。

VNC采用RFB通信协议,RFB ("remote 帧缓存 ") 是一个远程图形用户的简单协议,通过TCP/IP 协议簇连接。VNC控制端和被控制端在连接时会协商彼此支持的编码方式,编码方式已经发展出了很多种,有压缩率高的但编解码算法复杂,有压缩率低一些但编解码算法相对简单的,根据网络情况和客户端计算能力选择合适的。通常的编码方式是当原始的满屏被发送后,只发送变化的方块区域。分块算法和图像压缩技术随不同编码方式变化。目前采用的noVNC是用的Tight编码方式,按照相关测评数据[2],这是一个压缩率高比较节省带宽的编码方式。注:算法实现可以在aosp/6.0/system/external/libvncserver找到,或者在qemu2.4/ui/vnc-enc-xxx.c。

"Hextile" is an encoding that was designed for fast networks, while "Tight" is better suited for low-bandwidth connections. From the other side, "Tight" decoder in the TightVNC Java viewer seems to be more efficient than "Hextile" decoder so it may be ok for fast networks too. "ZRLE" encoding is similar to "Tight", but it does not support JPEG compression and compression levels.

8. 怎么给每台模拟器赋予一个imei?

部分应用通过判断IMEI是否是0来甄别模拟器,阻止在模拟器上运行。

Qemu/android_qemu/telephony/modem.c里CGSN处定义了IMEI的值,所以模拟器里显示的IMEI的值是0000000000。要修改这里获取IMEI的方法

9. Root的处理

App里通过su获得root权限代码:

需要注意的是,真机adb shell进去的默认是shell用户,模拟器里adb shell进去默认的就是root用户了,可以进行高权限的行为。模拟器镜像里也内置了su, 可以在shell里通过su命令切换shell/root用户,但是原始的su只可以由uid为AID_ROOT和AID_SHELL的进程调用,所以这些只是可以在PC端通过adb来使用。 第三方apk里是没法通过上面的java代码去切换到root用户的。

这就需要替换掉原始的su文件,突破进程校验的限制。这里借助了supersu提供的文件进行处理。用supersu提供的su文件替换原始的/system/bin/su,安装supersua.apk来进行权限管理。

基本原理是将apk层传入的本应放在shell进程中执行的命令,放到daemonsu 创建的进程sush中执行。其中daemonsu 为开机时启动的守护进程(init进程启动,user为root)。

这个过程最重要的为:apk、su、daemonsu、sush、supersu.apk 之间的通信。

通信过程大概为:

1、三方进程调用su,su 通过socket 与 daemonsu 通信,

2、daemonsu 创建sush,

3、sush 通过 am 启动 superuser apk ,让用户选择是否授予其root权限。

4、supersu.apk 通过socket 告知 sush 用户选择的结果

5、sush 根据 apk 传过来的结果,选择继续执行或中断执行

其他:

1. 有时候会看到goldfish这个名词,按照文档说明,goldfish是专门为了模拟器运行的虚拟硬件平台的名字,早期只提供了模拟arm架构的处理器,现在已经有了x86和MIPS的。

'goldfish' is the name of a family of similar virtual hardware platforms, that

mostly differ in the virtual CPU they support. 'goldfish' started as an

ARM-specific platform, but has now been ported to x86 and MIPS virtual CPUs.

参考:

1.C语言编译详解

http://www.cnblogs.com/CarpenterLee/p/5994681.html

2.VNC

http://www.tightvnc.com/archive/compare.html

http://www.docin.com/p-1446032132.html

3.android emulator源码

https://android.googlesource.com/platform/external/qemu/+/master/docs/DEVELOPMENT.TXT

4.Houdini

http://blog.csdn.net/roland_sun/article/details/50132175

Android模拟器知识以及改造相关推荐

  1. Android基础知识——完善

    首页 下载App × Android基础知识--完善 布鲁马 2016.05.17 10:29* 字数 5478 阅读 2672评论 1喜欢 38 疯狂Android摘要,Android基础知识好乱好 ...

  2. 写给Android App开发人员看的Android底层知识合集(1-8)

    写给Android App开发人员看的Android底层知识合集(1-8) 转自包老师:http://www.cnblogs.com/Jax/p/6864103.html 写给Android App开 ...

  3. 使用Android模拟器调试linux内核

    使用Android模拟器调试linux内核 为什么需要调试linux内核 如何在Android上调试内核 开发环境 创建模拟器 下载goldfish内核源码 编译goldfish内核 编译内核遇到的问 ...

  4. Android基础知识~入门进阶,一步步走到高手

    Android基础知识~入门进阶,一步步走到高手 2011年09月01日 [b]希望新入手ANDROID设备的朋友认真阅读本帖,一些简单的问题就可以自己解决了!!! 一:基础知识[/b] [b]1.什 ...

  5. Android开发知识(一)(理论篇)

    之前学了很久的关于Android开发知识,只是很多的网课和博客都是很零碎的.这些零碎的知识对于小白来说,并不是一件好事,他们会觉得云里雾里,对Android产生抵触心理.在学了快六个月之后感觉自己终于 ...

  6. Android模拟器学framework和driver之传感器篇1(linux sensor driver)

    对于android模拟器开发环境的搭建这里我就不多说了,网上google下一大堆,还有就是android 模拟器的kernel使用的是goldfish的kernel,可以使用git得到源码,然后就可以 ...

  7. Android官方模拟器root,在Android模拟器上如何获得root权限?

    我需要在Android模拟器中获得root权限,从而使用'iptables'和'busybox'功能. 尝试安装了z4root应用程序, 但需要很长时间,且没有完成获取root就卡住了.有人说如果我们 ...

  8. 快到极致的Android模拟器——Genymotion

    转载声明:Ryan的博客文章欢迎您的转载,但在转载的同时,请注明文章的来源出处,不胜感激! :-) http://my.oschina.net/ryanhoo/blog/141824 还在用Andro ...

  9. android模拟器的数据存放,Android模拟器在哪里存储SQLite数据库?

    Android模拟器在哪里存储SQLite数据库? 我正在开发一个将数据存储在SQLite数据库中的Android应用程序. 我的问题是,当您使用模拟器时,此数据库文件存储在文件系统中的哪个位置? 我 ...

  10. atitit.android模拟器使用报告

    atitit.android模拟器使用报告 靠谱助手 仅仅7--15M,只助手,没android模拟器.. BlueStacks新版本App Player采用名为Layercake的技术,可以让针对A ...

最新文章

  1. 【C语言】 strstr查找子字符串函数以及模拟实现讲解
  2. 洛谷 P2679 子串 【dp神题】【滚动数组】【2015 noip d2t2】
  3. apache和tomcat区别
  4. boost::hana::unpack用法的测试程序
  5. angular.js国际化模块
  6. C++程序的单元测试
  7. 常见的Activity Action Intent常量
  8. C语言-按照单词反转字符串(完整代码)
  9. 结构体与共用体07 - 零基础入门学习C语言59
  10. 爱数智慧荣获“阿里云2021年度优秀供应商” | 喜讯
  11. c语言文件操作rewand,C语言程序设计第章概述.ppt
  12. 组态软件调用matlab,()基于OPC的组态软件和MATLAB的通信实现
  13. 简账(开源记账软件)-后端环境简介及部署
  14. java 修改分辨率_JAVA程序分辨率修改及自适屏修改
  15. echarts官网文档打开慢的解决方法
  16. 探索汽车行业大数据应用
  17. 上班划水,给男朋友做个数字炸弹游戏
  18. PMP考纲解读 |【人】任务3—支持团队绩效(二)
  19. STM32F103采集光照传感器BH1750程序,测试可以用
  20. 乌镇·Conflux CTO伍鸣:让公链的“不可能三角”成为可能

热门文章

  1. 浅谈医疗卫生系统人事档案管理
  2. R语言——符号函数(向量化)
  3. 兼容android 6.0以上获取设备编号等权限
  4. MAMP配置虚拟主机
  5. 音视频又贵又卡还不够炫?云原生的华为云视频云服务带你重塑新体验
  6. 一段让你虎躯一震的代码
  7. Elasticsearch 最佳运维实践总结
  8. 基于微信图书馆教室座位预约小程序系统设计与实现 开题报告
  9. 【BBF系列协议】TR104 VoIP CPE的配置参数
  10. 【20年9月】聊聊我的CISM备考过程,有经验有教训!