配置环境
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
3. PUB_CACHE 如果项目和flutterSDK不在同一盘符,就需要配置该变量,目录指向项目所在的盘符
D:\src\flutter_pub_cache
4. FLUTTER_STORAGE_BASE_URL
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; } @override Widget build() => state.build(this); State<StatefulWidget> get state => _state!; State<StatefulWidget>? _state; @override void reassemble() { if (_debugShouldReassemble(_debugReassembleConfig, _widget)) { state.reassemble(); } super.reassemble(); } @override void _firstBuild() { assert(state._debugLifecycleState == _StateLifecycle.created); final Object? debugCheckForReturnedFuture = state.initState() as dynamic; state.didChangeDependencies(); super._firstBuild(); } @override void performRebuild() { if (_didChangeDependencies) { state.didChangeDependencies(); _didChangeDependencies = false; } super.performRebuild(); } @override void update(StatefulWidget newWidget) { super.update(newWidget); final Object? debugCheckForReturnedFuture = state.didUpdateWidget(oldWidget) as dynamic; rebuild(force: true); } @override void activate() { super.activate(); markNeedsBuild(); } @override void deactivate() { state.deactivate(); super.deactivate(); } @override void unmount() { super.unmount(); state.dispose(); state._element = null; _state = null; } @override InheritedWidget dependOnInheritedElement(Element ancestor, { Object? aspect }) { return super.dependOnInheritedElement(ancestor as InheritedElement, aspect: aspect); } bool _didChangeDependencies = false; @override void didChangeDependencies() { super.didChangeDependencies(); _didChangeDependencies = true; } }
State
@optionalTypeArgs 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; @protected @mustCallSuper void initState() { assert(_debugLifecycleState == _StateLifecycle.created); } @mustCallSuper @protected void didUpdateWidget(covariant T oldWidget) { } @protected @mustCallSuper void reassemble() { } @protected void setState(VoidCallback fn) { assert(() { return true; }()); final Object? result = fn() as dynamic; _element!.markNeedsBuild(); } @protected @mustCallSuper void deactivate() { } @protected @mustCallSuper void activate() { } @protected @mustCallSuper void dispose() { assert(_debugLifecycleState == _StateLifecycle.ready); assert(() { _debugLifecycleState = _StateLifecycle.defunct; return true; }()); if (kFlutterMemoryAllocationsEnabled) { MemoryAllocations.instance.dispatchObjectDisposed(object: this); } } @protected Widget build(BuildContext context); @protected @mustCallSuper 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 { } } @pragma('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); } } @pragma('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); } @protected @mustCallSuper void performRebuild() { _dirty = false; } @mustCallSuper 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(); } } @override InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect }) { _dependencies ??= HashSet<InheritedElement>(); _dependencies!.add(ancestor); ancestor.updateDependencies(this, aspect); return ancestor.widget as InheritedWidget; } @override 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; } @override T? getInheritedWidgetOfExactType<T extends InheritedWidget>() { return getElementForInheritedWidgetOfExactType<T>()?.widget as T?; } @protected @pragma('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; } @mustCallSuper void update(covariant Widget newWidget) { assert( _lifecycleState == _ElementLifecycle.active && newWidget != widget && Widget.canUpdate(widget, newWidget), ); _widget = newWidget; } @protected @pragma('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; @override bool get debugDoingBuild => _debugDoingBuild; @override 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. } @override @pragma('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); } } @protected Widget build(); @override void visitChildren(ElementVisitor visitor) { if (_child != null) { visitor(_child!); } } @override void forgetChild(Element child) { assert(child == _child); _child = null; super.forgetChild(child); } }
ProxyElement InheritedElement
class ProxyElement{ @override void update(ProxyWidget newWidget) { final ProxyWidget oldWidget = widget as ProxyWidget; assert(widget != newWidget); super.update(newWidget); assert(widget == newWidget); updated(oldWidget); rebuild(force: true); } @protected void updated(covariant ProxyWidget oldWidget) { notifyClients(oldWidget); } } class InheritedElement{ @override 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’
}