内容简介:看过由于 Zygote 在系统启动时冷启动了一个Linux内核启动后,就开始了初始化 Android 系统(init process)的过程。/system/bin/app_process 运行并启动了 Android运行时(AndroidRuntime.start()),在这期间运行时启动了Dalvik 虚拟机,并且创建了zygote进程,以及开启com.android.server.SystemServer 系统服务进程。Zygote将在有新的应用启动时被激活,为了加速应用启动的过程,Zygote会预
看过 vysor原理以及Android同屏方案 , 我突然想到整个过程应该如何验证的问题。于是反编译了vysor 最新的apk, 其中的代码逻辑依然具有很强的借鉴意义。其中通过 shell
环境下调用 adb
获取截屏权限成为了全篇的亮点所在。以下文字简要地记录了个人的理解过程,同时希望增进对Android Framework 的理解。
0. 背景介绍
关于App的创建
由于 Zygote 在系统启动时冷启动了一个 Dalvik
/ ART
VM
, 并开启对创建新APP请求的监听。随后所有新的应用进程都由Zygote 执行 fork 操作而创建的。具体流程如下所述:
Linux内核启动后,就开始了初始化 Android 系统(init process)的过程。/system/bin/app_process 运行并启动了 Android运行时(AndroidRuntime.start()),在这期间运行时启动了Dalvik 虚拟机,并且创建了zygote进程,以及开启com.android.server.SystemServer 系统服务进程。Zygote将在有新的应用启动时被激活,为了加速应用启动的过程,Zygote会预加载公用的 Java 类和资源到RAM中,以供应用在实际运行时使用。最终,Zygote将执行fork操作生成子进程,并启动这一新的应用进程。
Android Boot Sequence (from Embedded Android)
Java 应用与 Android app的差异
从以上Android APP的编译流程上,我们也不难看出:由于Android 平台使用了一个不同于一般 JVM 的虚拟机,这就使得Java class 文件需要额外的处理(即 dex化)之后才能运行。
作为一个"推进器",上述 app_process
除了启动 Zygote
进程外,还可以创建其它进程。有兴趣的读者可以进一步参考链接中的 Run a Java main on Android 部分, 在命令行中实际编译Java代码, dex
处理以及通过 adb shell
命令打印出 Android 平台上的"Hello World"。
1. 实现
先上一个截取屏幕并在浏览器中显示的效果图:
1.0 与截屏的相关API
在OS 4.3 之前有标注为( @hide
)的API android.view.Surface.screenshot ()
; 而4.3之后API变为 android.view.SurfaceControl.screenshot()
. 非root的设备上,一般的APP是没有权限调用以上的接口的。而在 shell
环境下确实具备权限的,而这正一点好成为了一个突破口。
1.1 代码入口方法
Java 类 Main
的静态方法 main()
中简单实现了一个 HandlerThread
(可类比源码中 ActivityThread.main() )。在looper 正在开始处理消息前,启动本地的server, 并设置对screenshot GET请求的回调方法。回调处理过程使用上述的 screenshot()
方法进行屏幕截图,并设置Bitmap数据为对应的 HTTP response。最后设置 adb forward tcp:53516 tcp:53516
将PC上所有 53516 端口通信数据重定向到手机端 53516 端口server上。
1.2 调用隐藏的API
在App内部,通常在有 Context 的情况下我们可以很方便地获取系统服务: WindowManager window = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
而此时的入口 Main 是由 app_process 启动的一个独立进程。于是问题就出现了,如何获取当前屏幕的宽和高呢?想想框架中的 Java 部分代码是如何进行进程间通信的,常见的AIDL 成为了一个较好的方案。同样利用框架提供的 WINDOW_SERVICE
, 我们可以将系统源码中的 IWindowManager.aidl 拷贝到工程目录中,利用对应生成的local stub 通过编译,运行时通过反射调用对应所需的服务。
1.3 自动化ADB设置的命令行工具
有关命令行 工具 的实现 cmd_runner.c
已实现自动化的任务包括 forward/unforward PC网络请求,通过管道 (pipe) 跨进程通信得到已安装APP的实际路径,以及 shell 环境下调用 app_process
启动内部截图服务等。
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 动画+原理+代码,解读十大经典排序算法
- Ozone原理|Ratis代码解析之一-gRPC
- iOS覆盖率检测原理与增量代码
- 移动端下拉刷新头实现原理及代码实现
- 编译原理学习一,去除代码中的注释
- 负载均衡的几种算法原理及代码实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Effective JavaScript
David Herman / Addison-Wesley Professional / 2012-12-6 / USD 39.99
"It's uncommon to have a programming language wonk who can speak in such comfortable and friendly language as David does. His walk through the syntax and semantics of JavaScript is both charming and h......一起来看看 《Effective JavaScript》 这本书的介绍吧!