配置环境
1. resolve.dependencies.gradle
Flutter安装目录/packages/flutter_tools/gradle/resolve.dependencies.gradle
maven {
url "https://maven.aliyun.com/repository/public/"
}
maven {
url "https://maven.aliyun.com/repository/central"
}
maven {
url "https://maven.aliyun.com/repository/google"
}
2. PUB_HOSTED_URL
https://pub.flutter-io.cn
3. PUB_CACHE 如果项目和flutterSDK不在同一盘符,就需要配置该变量,目录指向项目所在的盘符
D:\src\flutter_pub_cache
4. FLUTTER_STORAGE_BASE_URL
https://storage.flutter-io.cn
5. 终端代理命令
export https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890
6. 其他
- xxx_android.iml 该文件可以让as 提示Open for Editing in Android Studio
- settings.gradle 定义了dev.flutter.flutter-gradle-plugin插件
生命周期
- WidgetsBindingObserver(AppLifecycleState)
- AppLifecycleListener
- State
页面展示
- 构造方法->initState->didChangeDependencies-build(到这一步页面展示出来了)
- AppLifecycleState.resumed
前台切回后台
- AppLifecycleState.inactive->AppLifecycleState.hidden
- ->AppLifecycleState.paused
- AppLifecycleListener.inactive->AppLifecycleListener.hide
- ->AppLifecycleListener.pause
后台切回前台
- AppLifecycleState.hidden->AppLifecycleState.inactive
- ->AppLifecycleState.resumed
- AppLifecycleListener.restart->AppLifecycleListener.show
- ->AppLifecycleListener.resume
页面销毁
- AppLifecycleState.inactive->AppLifecycleState.hidden->AppLifecycleState.paused->AppLifecycleState.detached->deactivate->dispose
- AppLifecycleListener.hide->AppLifecycleListener.pause->AppLifecycleListener.detach
源码分析生命周期
ui的重绘都需要Widget的构建,也是就调用State.build或者StateLessWidget.build方法,
Element->markNeedsBuild-标记_dirty=true
调用Element.markNeedsBuild几个方法
- 开发者直接调用
State.setState- 修改依赖属性,会导致依赖发生变化
InheriteWidget-update-updated-notifyClients-notifyClient-dependent.didChangeDependencies
Eelement.didChangeDependencies- StateFulElement.activate
ComponentElement.mount()->StatefulElement._firstBuild->state.initState()->state.didChangeDependencies()->rebuild()->StatefulElement.performRebuild()->第一次不会调用state.didChangeDependencies()因为_didChangeDependencies=fasle,后面会通过调用activited->state.activate()并且调用StatefulElement.didChangeDependencies()方法_didChangeDependencies = true
update->state.didUpdateWidget->rebuild->…
RenderObjectToWidgetElement->update->…
didUpdateWidget
- 自身state会导致自身build方法调用
- 父state会导致非const子组件的didUpdateWidget调用
didChangeDependencies
- InheritedWidget共享数据发生变化的时候
- 获取共享数据用到的context 对应的state的
- 通过父widget的setstate更新依赖的数据导致子组件的state.didChangeDependencies
BuildOwner通过StatefulElement间接驱动了state各个生命周期的触发
StatefulElement
class StatefulElement extends ComponentElement {
StatefulElement(StatefulWidget widget)
: _state = widget.createState(),
super(widget) {
state._element = this;
state._widget = widget;
}
Widget build() => state.build(this);
State<StatefulWidget> get state => _state!;
State<StatefulWidget>? _state;
void reassemble() {
if (_debugShouldReassemble(_debugReassembleConfig, _widget)) {
state.reassemble();
}
super.reassemble();
}
void _firstBuild() {
assert(state._debugLifecycleState == _StateLifecycle.created);
final Object? debugCheckForReturnedFuture = state.initState() as dynamic;
state.didChangeDependencies();
super._firstBuild();
}
void performRebuild() {
if (_didChangeDependencies) {
state.didChangeDependencies();
_didChangeDependencies = false;
}
super.performRebuild();
}
void update(StatefulWidget newWidget) {
super.update(newWidget);
final Object? debugCheckForReturnedFuture = state.didUpdateWidget(oldWidget) as dynamic;
rebuild(force: true);
}
void activate() {
super.activate();
markNeedsBuild();
}
void deactivate() {
state.deactivate();
super.deactivate();
}
void unmount() {
super.unmount();
state.dispose();
state._element = null;
_state = null;
}
InheritedWidget dependOnInheritedElement(Element ancestor, { Object? aspect }) {
return super.dependOnInheritedElement(ancestor as InheritedElement, aspect: aspect);
}
bool _didChangeDependencies = false;
void didChangeDependencies() {
super.didChangeDependencies();
_didChangeDependencies = true;
}
}
State
class State {
T get widget => _widget!;
T? _widget;
BuildContext get context {
assert(() {
if (_element == null) {
}
return true;
}());
return _element!;
}
StatefulElement? _element;
bool get mounted => _element != null;
void initState() {
assert(_debugLifecycleState == _StateLifecycle.created);
}
void didUpdateWidget(covariant T oldWidget) { }
void reassemble() { }
void setState(VoidCallback fn) {
assert(() {
return true;
}());
final Object? result = fn() as dynamic;
_element!.markNeedsBuild();
}
void deactivate() { }
void activate() { }
void dispose() {
assert(_debugLifecycleState == _StateLifecycle.ready);
assert(() {
_debugLifecycleState = _StateLifecycle.defunct;
return true;
}());
if (kFlutterMemoryAllocationsEnabled) {
MemoryAllocations.instance.dispatchObjectDisposed(object: this);
}
}
Widget build(BuildContext context);
void didChangeDependencies() { }
}
BuildOwner
class BuildOwner {
BuildOwner({ this.onBuildScheduled, FocusManager? focusManager }) :
focusManager = focusManager ?? (FocusManager()..registerGlobalHandlers());
VoidCallback? onBuildScheduled;
final _InactiveElements _inactiveElements = _InactiveElements();
final List<Element> _dirtyElements = <Element>[];
bool _scheduledFlushDirtyElements = false;
bool? _dirtyElementsNeedsResorting;
FocusManager focusManager;
void scheduleBuildFor(Element element) {
if (element._inDirtyList) {
_dirtyElementsNeedsResorting = true;
return;
}
if (!_scheduledFlushDirtyElements && onBuildScheduled != null) {
_scheduledFlushDirtyElements = true;
onBuildScheduled!();
}
_dirtyElements.add(element);
element._inDirtyList = true;
}
void lockState(VoidCallback callback) {
try {
callback();
} finally {
}
}
('vm:notify-debugger-on-exception')
void buildScope(Element context, [ VoidCallback? callback ]) {
if (callback == null && _dirtyElements.isEmpty) {
return;
}
if (!kReleaseMode) {
Map<String, String>? debugTimelineArguments;
FlutterTimeline.startSync(
'BUILD',
arguments: debugTimelineArguments
);
}
try {
_scheduledFlushDirtyElements = true;
if (callback != null) {
Element? debugPreviousBuildTarget;
_dirtyElementsNeedsResorting = false;
try {
callback();
} finally {
}
}
_dirtyElements.sort(Element._sort);
_dirtyElementsNeedsResorting = false;
int dirtyCount = _dirtyElements.length;
int index = 0;
while (index < dirtyCount) {
final Element element = _dirtyElements[index];
final bool isTimelineTracked = !kReleaseMode && _isProfileBuildsEnabledFor(element.widget);
if (isTimelineTracked) {
Map<String, String>? debugTimelineArguments;
FlutterTimeline.startSync(
'${element.widget.runtimeType}',
arguments: debugTimelineArguments,
);
}
try {
element.rebuild();
} catch (e, stack) {
}
if (isTimelineTracked) {
FlutterTimeline.finishSync();
}
index += 1;
if (dirtyCount < _dirtyElements.length || _dirtyElementsNeedsResorting!) {
_dirtyElements.sort(Element._sort);
_dirtyElementsNeedsResorting = false;
dirtyCount = _dirtyElements.length;
while (index > 0 && _dirtyElements[index - 1].dirty) {
index -= 1;
}
}
}
} finally {
for (final Element element in _dirtyElements) {
element._inDirtyList = false;
}
_dirtyElements.clear();
_scheduledFlushDirtyElements = false;
_dirtyElementsNeedsResorting = null;
if (!kReleaseMode) {
FlutterTimeline.finishSync();
}
}
}
final Map<GlobalKey, Element> _globalKeyRegistry = <GlobalKey, Element>{};
int get globalKeyCount => _globalKeyRegistry.length;
void _registerGlobalKey(GlobalKey key, Element element) {
_globalKeyRegistry[key] = element;
}
void _unregisterGlobalKey(GlobalKey key, Element element) {
if (_globalKeyRegistry[key] == element) {
_globalKeyRegistry.remove(key);
}
}
('vm:notify-debugger-on-exception')
void finalizeTree() {
if (!kReleaseMode) {
FlutterTimeline.startSync('FINALIZE TREE');
}
try {
lockState(_inactiveElements._unmountAll); // this unregisters the GlobalKeys
} catch (e, stack) {
} finally {
if (!kReleaseMode) {
FlutterTimeline.finishSync();
}
}
}
}
Element
class Element {
Set<InheritedElement>? _dependencies;
void markNeedsBuild() {
assert(_lifecycleState != _ElementLifecycle.defunct);
if (_lifecycleState != _ElementLifecycle.active) {
return;
}
if (dirty) {
return;
}
_dirty = true;
owner!.scheduleBuildFor(this);
}
void rebuild({bool force = false}) {
try {
performRebuild();
} finally {
assert(() {
owner!._debugElementWasRebuilt(this);
assert(owner!._debugCurrentBuildTarget == this);
owner!._debugCurrentBuildTarget = debugPreviousBuildTarget;
return true;
}());
}
assert(!_dirty);
}
void performRebuild() {
_dirty = false;
}
void activate() {
assert(_lifecycleState == _ElementLifecycle.inactive);
assert(owner != null);
final bool hadDependencies = (_dependencies != null && _dependencies!.isNotEmpty) || _hadUnsatisfiedDependencies;
_dependencies?.clear();
_hadUnsatisfiedDependencies = false;
_updateInheritance();
attachNotificationTree();
if (_dirty) {
owner!.scheduleBuildFor(this);
}
if (hadDependencies) {
didChangeDependencies();
}
}
InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect }) {
_dependencies ??= HashSet<InheritedElement>();
_dependencies!.add(ancestor);
ancestor.updateDependencies(this, aspect);
return ancestor.widget as InheritedWidget;
}
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object? aspect}) {
assert(_debugCheckStateIsActiveForAncestorLookup());
final InheritedElement? ancestor = _inheritedElements == null ? null : _inheritedElements![T];
if (ancestor != null) {
return dependOnInheritedElement(ancestor, aspect: aspect) as T;
}
_hadUnsatisfiedDependencies = true;
return null;
}
T? getInheritedWidgetOfExactType<T extends InheritedWidget>() {
return getElementForInheritedWidgetOfExactType<T>()?.widget as T?;
}
('vm:prefer-inline')
Element? updateChild(Element? child, Widget? newWidget, Object? newSlot) {
if (newWidget == null) {
if (child != null) {
deactivateChild(child);
}
return null;
}
final Element newChild;
if (child != null) {
bool hasSameSuperclass = true;
assert(() {
final int oldElementClass = Element._debugConcreteSubtype(child);
final int newWidgetClass = Widget._debugConcreteSubtype(newWidget);
hasSameSuperclass = oldElementClass == newWidgetClass;
return true;
}());
if (hasSameSuperclass && child.widget == newWidget) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
newChild = child;
} else if (hasSameSuperclass && Widget.canUpdate(child.widget, newWidget)) {
if (child.slot != newSlot) {
updateSlotForChild(child, newSlot);
}
final bool isTimelineTracked = !kReleaseMode && _isProfileBuildsEnabledFor(newWidget);
if (isTimelineTracked) {
Map<String, String>? debugTimelineArguments;
Timeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
}
child.update(newWidget);
if (isTimelineTracked) {
Timeline.finishSync();
}
assert(child.widget == newWidget);
assert(() {
child.owner!._debugElementWasRebuilt(child);
return true;
}());
newChild = child;
} else {
deactivateChild(child);
assert(child._parent == null);
newChild = inflateWidget(newWidget, newSlot);
}
} else {
newChild = inflateWidget(newWidget, newSlot);
}
return newChild;
}
void update(covariant Widget newWidget) {
assert(
_lifecycleState == _ElementLifecycle.active
&& newWidget != widget
&& Widget.canUpdate(widget, newWidget),
);
_widget = newWidget;
}
('vm:prefer-inline')
Element inflateWidget(Widget newWidget, Object? newSlot) {
final bool isTimelineTracked = !kReleaseMode && _isProfileBuildsEnabledFor(newWidget);
if (isTimelineTracked) {
Map<String, String>? debugTimelineArguments;
FlutterTimeline.startSync(
'${newWidget.runtimeType}',
arguments: debugTimelineArguments,
);
}
try {
final Key? key = newWidget.key;
if (key is GlobalKey) {
final Element? newChild = _retakeInactiveElement(key, newWidget);
if (newChild != null) {
try {
newChild._activateWithParent(this, newSlot);
} catch (_) {
try {
deactivateChild(newChild);
} catch (_) {
// Clean-up failed. Only surface original exception.
}
rethrow;
}
final Element? updatedChild = updateChild(newChild, newWidget, newSlot);
assert(newChild == updatedChild);
return updatedChild!;
}
}
final Element newChild = newWidget.createElement();
newChild.mount(this, newSlot);
return newChild;
} finally {
if (isTimelineTracked) {
FlutterTimeline.finishSync();
}
}
}
}
ComponentElement
abstract class ComponentElement extends Element {
ComponentElement(super.widget);
Element? _child;
bool _debugDoingBuild = false;
bool get debugDoingBuild => _debugDoingBuild;
void mount(Element? parent, Object? newSlot) {
super.mount(parent, newSlot);
_firstBuild();
assert(_child != null);
}
void _firstBuild() {
// StatefulElement overrides this to also call state.didChangeDependencies.
rebuild(); // This eventually calls performRebuild.
}
('vm:notify-debugger-on-exception')
void performRebuild() {
Widget? built;
try {
built = build();
} catch (e, stack) {
_debugDoingBuild = false;
} finally {
super.performRebuild(); // clears the "dirty" flag
}
try {
_child = updateChild(_child, built, slot);
assert(_child != null);
} catch (e, stack) {
_child = updateChild(null, built, slot);
}
}
Widget build();
void visitChildren(ElementVisitor visitor) {
if (_child != null) {
visitor(_child!);
}
}
void forgetChild(Element child) {
assert(child == _child);
_child = null;
super.forgetChild(child);
}
}
ProxyElement InheritedElement
class ProxyElement{
void update(ProxyWidget newWidget) {
final ProxyWidget oldWidget = widget as ProxyWidget;
assert(widget != newWidget);
super.update(newWidget);
assert(widget == newWidget);
updated(oldWidget);
rebuild(force: true);
}
void updated(covariant ProxyWidget oldWidget) {
notifyClients(oldWidget);
}
}
class InheritedElement{
void notifyClients(InheritedWidget oldWidget) {
for (final Element dependent in _dependents.keys) {
assert(() {
Element? ancestor = dependent._parent;
while (ancestor != this && ancestor != null) {
ancestor = ancestor._parent;
}
return ancestor == this;
}());
notifyDependent(oldWidget, dependent);
}
}
}
图片
build
createState
state.element = this
state.widget = widget
firstBuild
initState()
didChangeDipendcies
super.firstBuild->rebuild->performRebuild->didChangeDependencies->build
update->didUpdate->rebuild->performRebuild->didChangeDependencies->build
setState调用当前组件的build,调用子组件的update方法
setState->Element.markNeedsBuild->BuildOwner.scheduleBuildFor->
Element
bool _inDirtyList
bool _dirty 在下一次Vsync信号的时候会build
BuildOwner
List _dirtyElements
bool _scheduledFlushDirtyElements
buildScope rebuild
WidgetsBinding
_handleBuildScheduled->ensureVisualUpdate->scheduleFrame->PlatformDispatcher.scheduleFrame Vsync信号注册完成
drawFrame()->buildScope
SchedulerBinding
handleBeginFrame->PlatformDispatcher.onBeginFrame
handleDrawFrame->PlatformDispatcher.onDrawFrame
android 事件机制
dispatcheTouchEvent->onInterceptTouchEvent->子控件
接收到任务分发(diapatchTouchEvent)
总经理->部门主管->员工
拦截任务(onInterceptTouchEvent,只有viewgroup有这个方法,如果哪一级部门拦截就不会再向下一级部门分发)
总经理->部门主管->员工
//处理任务消耗(onTouchEvent true自己处理(包括后续事件MOVE UP),,false返回给上级处理)
总经理->部门主管->员工
//反馈处理结果
总经理<-部门主管<-员工
总经理收到任务并通知到最小员工,如果中间有部门拦截并处理,就不会向下传递,否则继续向下传递
员工看是否有能力处理,如果有就处理,没有返回给上一级主管反馈情况
开发插件和package
1.修改pubspec.yaml文件 名字描述 版本 作者 github主页
2.reademe.md
3.LICENSE
检查
flutter packages pub publish --dry-run
发布
flutter packages pub publish
依赖包冲突
多个依赖都引用第三方依赖
直接在下面引用这个第三方依赖 优先级最高
打包存在多个一样的so文件,冲突
packagingOptions {
pickFirst ‘**/libstlport_shared.so’
}