一、引言
DoraemonKit是滴滴开源的研发助手组件,目前支持iOS和Android两个平台。通过接入DoraemonKit组件,可以方便支持如下所示的多种调试工具:
本文是DoraemonKit之Android版本技术实现系列文章的第一篇,主要介绍各个视觉工具的技术实现细节。
二、技术实现
2.1 取色器
方案对比
取色器工具可以通过颜色吸管获取屏幕任意位置的像素值,所以实现的关键就是如何获取像素点。获取像素点的第一步是获取屏幕截图,获取屏幕截图在Android平台主要有以下几种方式:
- 通过View的getDrawingCache方法
- 通过读取系统FrameBuffer
- 通过MediaProjectionManager类
对比三种实现方式,方式一只能获取当前Window内DocorView的内容,不能获取状态栏或者脱离应用本身,且开启DrawingCache会增加应用内存占用;方式二中FrameBuffer不能直接读取,需要获得系统Root权限,且兼容性差;方式三可脱离应用本身获取应用外截屏,截图取自系统Binder不占用应用内存,只需请求录屏权限。
getDrawingCache函数 | 读取系统FrameBuffer | MediaProjectionManager类 | |
---|---|---|---|
实现复杂度 | 简单 | 复杂 | 较简单 |
需要权限 | 无 | Root权限 | 录屏权限 |
适用性 | 只能截取应用内 | 应用内外都支持 | 应用内外都支持 |
性能影响 | 大 | 小 | 小 |
通过对比,DoraemonKit选择方式三作为取色器的实现方案。
请求录屏权限
private boolean requestCaptureScreen() {
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
return false;
}
MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if (mediaProjectionManager == null) {
return false;
}
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), RequestCode.CAPTURE_SCREEN);
return true;
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RequestCode.CAPTURE_SCREEN && resultCode == Activity.RESULT_OK) {
showColorPicker(data);
...
} else {
...
}
}
复制代码
通过createScreenCaptureIntent()方法可以获取请求系统录屏权限的Intent,然后调用startActivityForResult,系统会自动弹出权限授予弹窗。如果授予权限则在onActivityResult中得到系统回调成功,且返回录屏的resultData。
创建ImageReader
public void init(Context context, Bundle bundle) {
mMediaProjectionManager = (MediaProjectionManager) context.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if (mMediaProjectionManager != null) {
Intent intent = new Intent();
intent.putExtras(bundle);
mMediaProjection = mMediaProjectionManager.g