super.initInstances();

_instance = this;

// 这里

buildOwner.onBuildScheduled = _handleBuildScheduled;

window.onLocaleChanged = handleLocaleChanged;window.onAccessibilityFeaturesChanged = handleAccessibilityFeaturesChanged;

SystemChannels.navigation.setMethodCallHandler(_handleNavigationInvocation);

SystemChannels.system.setMessageHandler(_handleSystemMessage); FlutterErrorDetails.propertiesTransformers.add(transformDebugCreator);

}

}

我们可以看到buildOwner.onBuildScheduled回调等于了_handleBuildScheduled,那现在来看看这个_handleBuildScheduled方法:

void _handleBuildScheduled() {

//调用ensureVisualUpdate

ensureVisualUpdate();

}

可以看到调用ensureVisualUpdate方法,那我们继续走下去。

SchedulerBinding类ensureVisualUpdate方法


void ensureVisualUpdate() {

switch (schedulerPhase) {

case SchedulerPhase.idle:

case SchedulerPhase.postFrameCallbacks:

//当schedulerPhase为SchedulerPhase.idle,

//SchedulerPhase.postFrameCallbacks时调用

//scheduleFrame()

scheduleFrame();

return;

case SchedulerPhase.transientCallbacks:

case SchedulerPhase.midFrameMicrotasks:

case SchedulerPhase.persistentCallbacks:

return;

}

}

分别case了SchedulerPhase 的 5 个枚举值:

状态含义idle没有正在处理的帧,可能正在执行的是 WidgetsBinding.scheduleTask,scheduleMicrotask,Timer,事件 handlers,或者其他回调等transientCallbacksSchedulerBinding.handleBeginFrame 过程, 处理动画状态更新midFrameMicrotasks处理 transientCallbacks 阶段触发的微任务(Microtasks)persistentCallbacksWidgetsBinding.drawFrame 和 SchedulerBinding.handleDrawFrame 过程,build/layout/paint 流水线工作postFrameCallbacks主要是清理和计划执行下一帧的工作

第二个case调用scheduleFrame()方法


那我们看看scheduleFrame()方法

void scheduleFrame() {

if (_hasScheduledFrame || !_framesEnabled) return;

assert(() {

if (debugPrintScheduleFrameStacks)

debugPrintStack(

label: ‘scheduleFrame() called. Current phase is $schedulerPhase.’);

return true;

}());

//调用Window 的scheduleFrame方法是一个 native 方法

window.scheduleFrame();

_hasScheduledFrame = true;

}

WidgetsFlutterBinding 混入的这些 Binding 中基本都是监听并处理 Window 对象的一些事件,然后将这些事件按照 Framework 的模型包装、抽象然后分发。可以看到 WidgetsFlutterBinding 正是粘连 Flutter engine 与上层 Framework 的“胶水”。

名解释GestureBinding提供了 window.onPointerDataPacket 回调,绑定 Framework 手势子系统,是 Framework 事件模型与底层事件的绑定入口ServicesBinding提供了 window.onPlatformMessage 回调, 用于绑定平台消息通道(message channel),主要处理原生和 Flutter 通信SchedulerBinding提供了 window.onBeginFrame 和 window.onDrawFrame 回调,监听刷新事件,绑定 Framework 绘制调度子系统PaintingBinding绑定绘制库,主要用于处理图片缓存SemanticsBinding语义化层与 Flutter engine 的桥梁,主要是辅助功能的底层支持RendererBinding提供了 window.onMetricsChanged 、window.onTextScaleFactorChanged 等回调。它是渲染树与 Flutter engine 的桥梁WidgetsBinding提供了 window.onLocaleChanged、onBuildScheduled 等回调。它是 Flutter widget 层与 engine 的桥梁

之前的文中有说过,UI 的绘制逻辑是在 Render 树中实现的,所以这里还来细看 RendererBinding 的逻辑。

RendererBinding


void initInstances() {

//监听Window对象的事件

ui.window

…onMetricsChanged = handleMetricsChanged

…onTextScaleFactorChanged = handleTextScaleFactorChanged

…onSemanticsEnabledChanged = _handleSemanticsEnabledChanged

…onSemanticsAction = _handleSemanticsAction;

//添加PersistentFrameCallback

addPersistentFrameCallback(_handlePersistentFrameCallback);

}

addPersistentFrameCallback 中添加 _handlePersistentFrameCallback 最终调用了 drawFrame 而 WidgetsBinding 重写了 RendererBinding 中的 drawFrame() 方法。最终发现我们又回到了 WidgetsBinding 这个类中,在 WidgetsBinding 中 drawFrame 的实现如下:

@override

void drawFrame() {

try {

if (renderViewElement != null)

// 重构需要更新的element

buildOwner.buildScope(renderViewElement);

super.drawFrame(); //调用RendererBinding的drawFrame()方法

buildOwner.finalizeTree();

}

}

在上面 scheduleBuildFor 方法介绍中有提到:“scheduleBuildFor 是把一个 element 添加到 _dirtyElements 链表,以便当[WidgetsBinding.drawFrame]中调用 buildScope 的时候能够重构 element。onBuildScheduled()是一个 BuildOwner 的回调”。在 drawFrame 中调用 buildOwner.buildScope(renderViewElement)更新 elements。

void buildScope(Element context, [ VoidCallback callback ]) {

while (index < dirtyCount) {

assert(_dirtyElements[index] != null);

assert(_dirtyElements[index]._inDirtyList);

assert(!_dirtyElements[index]._active || _dirtyElements[index]._debugIsInScope(context));

try {

//while 循环进行元素重构

_dirtyElements[index].rebuild();

} catch (e, stack) {

}

}

}

得出


自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip204888 (备注Android)
img

最后为了帮助大家深刻理解Android相关知识点的原理以及面试相关知识,这里放上我搜集整理的2019-2021BATJ 面试真题解析,我把大厂面试中常被问到的技术点整理成了PDF,包知识脉络 + 诸多细节。

节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。

《960全网最全Android开发笔记》

《379页Android开发面试宝典》

历时半年,我们整理了这份市面上最全面的安卓面试题解析大全
包含了腾讯、百度、小米、阿里、乐视、美团、58、猎豹、360、新浪、搜狐等一线互联网公司面试被问到的题目。熟悉本文中列出的知识点会大大增加通过前两轮技术面试的几率。

如何使用它?

1.可以通过目录索引直接翻看需要的知识点,查漏补缺。
2.五角星数表示面试问到的频率,代表重要推荐指数

《507页Android开发相关源码解析》

只要是程序员,不管是Java还是Android,如果不去阅读源码,只看API文档,那就只是停留于皮毛,这对我们知识体系的建立和完备以及实战技术的提升都是不利的。

真正最能锻炼能力的便是直接去阅读源码,不仅限于阅读各大系统源码,还包括各种优秀的开源库。

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img
秀的开源库。

[外链图片转存中…(img-wLkCaKC3-1712762013380)]

腾讯、字节跳动、阿里、百度等BAT大厂 2019-2021面试真题解析

[外链图片转存中…(img-3o8ATu06-1712762013380)]

资料太多,全部展示会影响篇幅,暂时就先列举这些部分截图

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-Ke0qOTUN-1712762013381)]

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐