with DoKitServicesBinding {
static WidgetsBinding ensureInitialized() {
if (WidgetsBinding.instance == null) DoKitWidgetsFlutterBinding();
return WidgetsBinding.instance;
}
}
mixin DoKitServicesBinding on BindingBase, ServicesBinding {
@override
BinaryMessenger createBinaryMessenger() {
return DoKitBinaryMessenger(super.createBinaryMessenger());
}
}
接下去把runApp的入口调用改成如下,就能实现BinaryMessenger的替换 static void _runWrapperApp(DoKitApp wrapper) { DoKitWidgetsFlutterBinding.ensureInitialized() …scheduleAttachRootWidget(wrapper) …scheduleWarmUpFrame(); } 至于Method Channel具体信息的捕获,只要hook住BinaryMessenger.handlePlatformMessage和BinaryMessenger.send两个方法就行了,具体可看DoKitBinaryMessenger这个类
控件检查
和路由功能类似,通过从根element向下遍历,在遍历过程中记录和选中的View有交集的所有RendereObjectElement,并且记录用以标志当前页面的RendereObjectElement,获取它的Route信息。遍历完成后,遍历记录下来的RendereObjectElement,过滤掉Route信息和当前页面不一致的,这些Element属于被遮盖住的页面。然后通过比对RendereObjectElement和选中View的交叉区域面积占RendereObjectElement面积的比例,占比最大的为当前选中的组件。 在Debug模式下可以获取选中组件在工程中的代码位置,将WidgetInspectorService.instance.selection.current赋值为选中element的renderObject,再调用WidgetInspectorService.instance.getSelectedSummaryWidget方法,会返回一个json字符串,解析这个字符串就能获取源码文件名、行列信息等。
日志查看
日志查看功能比较简单,只要使用runZoned方法替代runApp,传入zoneSpecification,就能为日志输出设置一个代理函数,在这个代理函数内进行日志捕获,同时,还可以为onError设置一个代理函数,在这里将捕获的异常也会传入到日志当中。
帧率
–
使用WidgetsBinding.instance.addTimingsCallback可以统计帧率信息,在每帧渲染完成时会触发回调,包含该帧渲染的信息。
内存
–
同VM信息,使用VMService可以获取到内存详细使用信息。
网络请求
Flutter自带的网络请求通过HttpClient类发送,只要hook住HttpClient的创建就可以hook整个网络请求的过程。查看HttpClient的构造函数可以发现,如果存在HttpOverrides,就会使用HttpOverrids来创建HttpClient
factory HttpClient({SecurityContext? context}) {
HttpOverrides? overrides = HttpOverrides.current;
if (overrides == null) {
return new _HttpClient(context);
}
return overrides.createHttpClient(context);
}
所以这里重写了一个HttpOverrids
class DoKitHttpOverrides extends HttpOverrides {
final HttpOverrides origin;
DoKitHttpOverrides(this.origin);
@override
HttpClient createHttpClient(SecurityContext context) {
if (origin != null) {
return DoKitHttpClient(origin.createHttpClient(context));
}
// 置空,防止递归调用,使得_HttpClient可以被初始化
HttpOverrides.global = null;
HttpClient client = DoKitHttpClient(new HttpClient(context: context));
// 创建完成后继续置回DoKitHttpOverrides
HttpOverrides.global = this;
return client;
}
}
替换HttpOverrides
HttpOverrides origin = HttpOverrides.current;
HttpOverrides.global = new DoKitHttpOverrides(origin);
hook住HttpClient方法后,对于请求和返回结果的hook过程就和Android中的HttpUrlConnection类似了,具体可以看DoKitHttpClient、DoKitHttpClientRequest、DoKitHttpClientResponse三个类。
版本API兼容
Flutter版本更新还是比较快的,每一个大版本更新都会带来一些API的变更,目前DoKit的方案需要重写一些framework层的类,在兼容多版本时就会有一些问题。以上面的BinaryMessager为例,1.17版本只有四个方法,用来hook的DoKitBinaryMessager是这么写的
class DoKitBinaryMessenger extends BinaryMessenger {
final MethodCodec codec = const StandardMethodCodec();
final BinaryMessenger origin;
DoKitBinaryMessenger(this.origin);
@override
Future handlePlatformMessage(String channel, ByteData data, callback) {
ChannelInfo info = saveMessage(channel, data, false);
PlatformMessageResponseCallback wrapper = (ByteData data) {
resolveResult(info, data);
callback(data);
};
return origin.handlePlatformMessage(channel, data, wrapper);
}
@override
Future send(String channel, ByteData message) async {
ChannelInfo info = saveMessage(channel, message, true);
ByteData result = await origin.send(channel, message);
resolveResult(info, result);
return result;
}
@override
void setMessageHandler(
String channel, Future Function(ByteData message) handler) {
origin.setMessageHandler(channel, handler);
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)
最后
**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。
《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门即可获取!
最后
**要想成为高级安卓工程师,必须掌握许多基础的知识。**在工作中,这些原理可以极大的帮助我们理解技术,在面试中,更是可以帮助我们应对大厂面试官的刁难。
[外链图片转存中…(img-qK7pKzuV-1712016639021)]
[外链图片转存中…(img-PWUy7BW9-1712016639021)]