dart的作用域

Dart 没有 「public」「private」等关键字,默许便是揭露的,私有变量运用 下划线 _开头。

Dart中var与dynamic的差异

运用var来声明变量,dart会在编译阶段自动推导出类型。而dynamic不在编译期间做类型检查而是在运转期间做类型校验。

Flutter 问题集锦

var 不能从头赋值为其他类型 。 dynamic能够从头赋值为其他类型,Object能够从头赋值为其他类型, String(固定类型)也不能从头赋值为其他类型

const和final的差异

运用进程中从来不会被修改的变量, 能够运用finalconst, 而不是var或许其他类型, Final 变量的值只能被设置一次; Const 变量在编译时就现已固定 (Const 变量 是隐式 Final 的类型.) 第一流 final 变量或类变量在第一次运用时被初始化。

你们之前的代码是空安全的吗?讲一下什么是空安全。相关操作符有哪些? late关键字

?. ?? ?=

dart 扩展有了解过吗?怎样运用?之前有没有在某些场景顶用到过。

假设一个flutter插件需求集成进两个App中,其间界面相同可是有些文案不同。比如说界面title:一个叫单词本,一个叫单词列表,一个是单词概况》 一个是进入概况》,假设相似这种状况咱们应该怎样处理?

dynamic类型的变量能够进行扩展吗?不能够

extension StringExtension on String {
  int toInt() {
    return int.parse(this);
  }
}

dart中有接口吗?

dart中没有接口,类便是接口,dart中子类有必要完结接口中的一切办法,哪怕对错笼统的办法?

Flutter 级联运算符(..)是什么?有什么好处?

  1. 级联运算符。

它减少了变量的界说而且能够让你在一个方针上接连调用多个方针上的办法。

querySelector('#confirm') // 获取方针。
  ..text = 'Confirm' // 调用成员变量。
  ..classes.add('important')
  ..onClick.listen((e) => window.alert('Confirmed!'));

等价于

var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e) => window.alert('Confirmed!'));
  1. 级联运算符能够嵌套吗。

级联运算符能够嵌套。

final addressBook = (AddressBookBuilder()
      ..name = 'jenny'
      ..email = 'jenny@example.com'
      ..phone = (PhoneNumberBuilder()
            ..number = '415-555-0100'
            ..label = 'home')
          .build())
    .build();

什么是命名结构函数?它的作用是什么?怎样运用?

运用命名结构函数可为一个类完结多个结构函数, 也能够运用命名结构函数来更清晰的标明函数目的:

class Point {
  num x, y;
  Point(this.x, this.y);
  // 命名结构函数
  Point.origin() {
    x = 0;
    y = 0;
  }
}

什么重定向结构函数?

有时结构函数的仅有目的是重定向到同一个类中的另一个结构函数。 重定向结构函数的函数体为空, 结构函数的调用在冒号 (:) 之后。

class Point {
  num x, y;
  // 类的主结构函数。
  Point(this.x, this.y);
  // 指向主结构函数
  Point.alongXAxis(num x) : this(x, 0);
}

断语(不用问)

// 承认变量值不为空。
assert(text != null);
// 承认变量值小于100。
assert(number < 100);
// 承认 URL 是否是 https 类型。
assert(urlString.startsWith('https'));

假设assert句子中的布尔条件为 false , 那么正常的程序履行流程会被中断。

assert 的第一个参数能够是解析为布尔值的任何表达式。 假设表达式成果为 true , 则断语成功,并持续履行。 假设表达式成果为 false , 则断语失利,并抛出反常 ([AssertionError]

简单说一下在flutter里async和await?

await的呈现会把await之前和之后的代码分为两部分,await并不像字面意思所表明的程序运转到这儿就堵塞了,而是立刻完毕当时函数的履行并回来一个Future,函数内剩余代码经过调度异步履行。 async是和await调配运用的,await只在async函数中呈现。在async 函数里能够没有await或许有多个await。

安卓手机有四核和八核,咱们怎样利用这些多核cpu?(对Isolate的了解?)

isolate是Dart对actor并发模式的完结。 isolate是有自己的内存和单线程操控的运转实体。isolate自身的意思是“阻隔”,由于isolate之间的内存在逻辑上是阻隔的。isolate中的代码是按次序履行的,任何Dart程序的并发都是运转多个isolate的成果。由于Dart没有同享内存的并发,没有竞赛的或许性所以不需求锁,也就不用担心死锁的问题。

那么应该在什么时分运用Future,什么时分运用Isolate呢?

  • 办法履行耗时在几毫秒或许几十毫秒以下的,咱们应该用Future
  • 办法履行耗时在百毫秒以上的咱们能够采用Isolate 别的咱们还能够依照一些场景分类来区别是应该运用Future仍是Isolate
  • 网络恳求
  • 文件操作
  • json解析
  • 加密解密等

dart异步

dart是单线程模型仍是多线程模型,单线程怎样做到异步作用的? (音讯行列)

  1. Dart 在单线程中是以音讯循环机制来运转的,其间包括两个使命行列,一个是“微使命行列” microtask queue,另一个叫做“事情行列” event queue。
  2. 进口函数 main() 履行完后,音讯循环机制便启动了。首要会依照先进先出的次序逐个履行微使命行列中的使命,当一切微使命行列履行完后便开端履行事情行列中的使命,事情使命履行完毕后再去履行微使命,如此循环往复,生生不息。

如图所示:

Flutter 问题集锦

在flutter里streams是什么?有几种streams?有什么场景用到它?

Stream 用来处理接连的异步操作,Stream 是一个笼统类,用于表明一序列异步数据的源。它是一种产生接连事情的方式,能够生成数据事情或许过错事情,以及流完毕时的完结事情 Stream 分单订阅流和广播流。 网络状况的监控

future和steam有什么不一样?

在 Flutter 中有两种处理异步操作的方式 Future 和 Stream,Future 用于处理单个异步操作,Stream 用来处理接连的异步操作。

future能够创立一个在微使命行列中运转的异步使命吗?

Future.sync同步履行,然后调度到microtask queue来完结自己,也便是一个堵塞使命,会堵塞当时线程,sync履行完结了之后代码才会走到下一行

运用过Bloc吗,说一下Bloc的运用进程

bloc模式解析

运用过Getx吗?你们状况办理是怎样做的?说一下Getx精干什么?

getx文档

(mixin)假设说,现在有这样一个需求:(假设有三种动物,猫,鱼,鸭子。有三种行为,游水,吃饭,爬树。其间他们都会吃饭,鱼和鸭子会游水,只要猫会爬树。这品种结构在dart中应该怎样设计? 假设他们有公共的办法完结呢?)

这不便是将implement替换成了with,abstract class替换成了mixin嘛,也太简单了。但仔细一看,咱们发现mixin里有办法的详细完结,这样能够防止接口的办法有必要在子类完结从而导致的代码冗余(Java 8经过关键字default也能够做到这一点)问题。简而言之,mixin相关于接口能够更好的防止代码冗余,使代码更加会集。

//行走
mixin Walker{
  void walk(){...}
}
//游水行为
mixin Swim{
  void swim(){...}
}
//翱翔行为,由于这个是笼统办法,所以有必要在要完结,不能调用super.flying()
mixin Flying {
  void flying();
}
//海豚能够游水
class Dolphin extends Mammal with Swim{
  @override
  void swim() {
    super.swim();
  }
}
//蝙蝠能够飞、行走
class Bat extends Mammal with Flying,Walk{
  @override
  void flying() {...}
  //掩盖Walk类中的walk办法
  @override
  void walk() {
    super.walk();
  }
}
//猫能够行走,这儿没有重写Walk中的办法
class Cat extends Mammal with Walk{}
//鸽子能够行走、飞
class Dove extends Bird with Flying,Walk{
  @override
  void flying() {...}
}
//鸭子能够行走、飞及游水
class Duck extends Bird with Walk,Flying,Swim{
  @override
  void flying() {...}
  @override
  void walk() {...}
}
//鲨鱼能够游水
class Shark extends Fish with Swim{...}
//飞鱼能够飞及游水
class FlyingFish extends Fish with Flying,Swim{
  @override
  void flying() {...}
}

Flutter 组件的生命周期

StatelessWidget

生命周期只要一个,便是build

  • buid
build 是用来创立 Widget 的,但由于 build 在每次界面改写的时分都会调用,
所以不要在 build 里写事务逻辑,能够把事务逻辑写到你的 StatelessWidget 的结构函数里。

StatefullWidget

StatefulWidget 的生命周期比较复杂,依次为:

  • createState

createState 是 StatefulWidget 里创立 State 的办法,当要创立新的 StatefulWidget 的时分,会当即履行 createState,而且只履行一次,createState 有必要要完结:

  • initState

前面的 createState 是在创立 StatefulWidget 的时分会调用,initState 是 StatefulWidget 创立完后调用的第一个办法,而且只履行一次,相似于 Android 的 onCreate、iOS 的 viewDidLoad(),所以在这儿 View 并没有烘托,可是这时 StatefulWidget 现已被加载到烘托树里了,这时 StatefulWidget 的mount的值会变为 true,直到dispose调用的时分才会变为 false。能够在initState里做一些初始化的操作。 在 overrideinitState的时分有必要要调用 super.initState():

  • didChangeDependencies

当 StatefulWidget 第一次创立的时分,didChangeDependencies办法会在initState办法之后当即调用,之后当 StatefulWidget 改写的时分,就不会调用了,除非你的 StatefulWidget 依靠的 InheritedWidget 发生变化之后,didChangeDependencies才会调用,所以didChangeDependencies有或许会被调用屡次。

这个函数会紧跟在initState之后调用,而且能够调用BuildContext.inheritFromWidgetOfExactType,那么BuildContext.inheritFromWidgetOfExactType的运用场景是什么呢?最经典的运用场景是

  • build

在 StatefulWidget 第一次创立的时分,build办法会在didChangeDependencies办法之后当即调用,别的一种会调用build办法的场景是,每逢 UI 需求从头烘托的时分(setState触发),build都会被调用,所以build会被屡次调用,然后 回来要烘托的 Widget。千万不要在build里做除了创立 Widget 之外的操作,由于这个会影响 UI 的烘托效率

  • addPostFrameCallback

addPostFrameCallback是 StatefulWidge 烘托完毕的回调,只会被调用一次,之后 StatefulWidget 需求改写 UI 也不会被调用,addPostFrameCallback的运用办法是在initState里添加回调:

import 'package:flutter/scheduler.dart';
@override
void initState() {
  super.initState();
  SchedulerBinding.instance.addPostFrameCallback((_) => {});
}
  • didUpdateWidget 祖先节点rebuild widget时调用 .当组件的状况改动的时分就会调用didUpdateWidget.(或许会调用屡次)

理论上setState的时分会调用,但我实际操作的时分发现只是做setState的操作的时分没有调用这个办法。而在我改动代码hot reload时分会调用didUpdateWidget并履行build…

实际上这儿flutter结构会创立一个新的Widget,绑定本State,并在这个函数中传递老的Widget。这个函数一般用于比较新、老Widget,看看哪些特点改动了,并对State做一些调整。

需求注意的是,涉及到controller的改动,需求在这个函数中移除老的controller的监听,并创立新controller的监听。

  • deactivate

当要将 State 方针从烘托树中移除的时分,就会调用deactivate生命周期,这标志着 StatefulWidget 将要毁掉,可是有时分 State 不会被毁掉,而是从头插入到烘托树种。

  • dispose

当 View 不需求再显示,从烘托树中移除的时分,State 就会永久的从烘托树中移除,就会调用dispose生命周期,这时分就能够在dispose里做一些取消监听、动画的操作,和initState是相反的。

怎样监听FlutterApp是在前台仍是后台?

AppLifecycleState 便是 App 的生命周期,有:

  • resumed
  • inactive
  • paused
  • suspending

假设想要知道 Flutter App 的生命周期,例如 Flutter 是在前台仍是在后台,就需求运用到WidgetsBindingObserver了,运用办法如下:

1.State 的类 mix WidgetsBindingObserver:

class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
    ...
}

2.在 State 的initState里添加监听:

@override
  void initState(){
    super.initState();
    WidgetsBinding.instance.addObserver(this);
  }

3.在 State 的dispose里移除监听:

 @override
  void dispose() {
    // TODO: implement dispose
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
  1. 在 State 里 overridedidChangeAppLifecycleState
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
  super.didChangeAppLifecycleState(state);
  if (state == AppLifecycleState.paused) {
    // went to Background
  }
  if (state == AppLifecycleState.resumed) {
    // came back to Foreground
  }
}

Flutter怎样与安卓或IOS通信?

Flutter 经过 PlatformChannel 与原生进行交互,其间 PlatformChannel 分为三种:

BasicMessageChannel:用于传递字符串和半结构化的信息。 MethodChannel:用于传递办法调用。Flutter自动调用Native的办法,并获取相应的回来值。 EventChannel:用于数据流(event streams)的通信。

main()和runApp()函数在flutter的作用别离是什么?有什么关系吗?

  • main函数是相似于java语言的程序运转进口函数
  • runApp函数是烘托根widget树的函数
  • 一般状况下runApp函数会在main函数里履行

(进步)Hot Restart 和 Hot Reload 有什么差异吗?

Hot Reload比Hot Restart快,Hot Reload会编译咱们文件里新加的代码并发送给dart虚拟机,dart会更新widgets来改动UI,而Hot Restart会让dart 虚拟机从头编译运用。另一方面也是由于这样, Hot Reload会保存之前的state,而Hot Restart回你重置一切的state回到初始值。

(进步)介绍下Widget、State、Context 概念

Widget:在Flutter中,简直一切东西都是Widget。将一个Widget想象为一个可视化的组件(或与运用可视化方面交互的组件),当你需求构建与布局直接或直接相关的任何内容时,你正在运用Widget。

Widget树:Widget以树结构进行组织。包括其他Widget的widget被称为父Widget(或widget容器)。包括在父widget中的widget被称为子Widget。

Context:仅仅是已创立的一切Widget树结构中的某个Widget的方位引证。简而言之,将context作为widget树的一部分,其间context所对应的widget被添加到此树中。一个context只从属于一个widget,它和widget一样是链接在一起的,而且会形成一个context树。

State:界说了StatefulWidget实例的行为,它包括了用于”交互/干预“Widget信息的行为和布局。运用于State的任何更改都会强制重建Widget。

有没有做过混合开发?混合开发单引擎和多引擎有什么差异。你感觉单引擎和引擎组哪种方式更好?

`FlutterEngineGroup``FlutterEngine`

混合开发中怎样对aar库进行依靠的?

有没有改动过官方的dart库,改动往后怎样依靠的?有没有建立过dart私服。

Expended组件运用时会有什么束缚吗?

讲一下你在Flutter中常常运用的有哪些组件?

Flutter GestureDetector 手势检测类用过吗?有时分分明设置了GestureDetector,可是却并不是悉数范围可点,只要中心部分有文案的地方能点击,请问是为什么怎样解决?

假设child不为null 则默以为 HitTestBehavior.deferToChild 假设child为null则默以为HitTestBehavior.translucent
HitTestBehavior.deferToChild:只要当时容器中的child被点击时才会呼应点击事情  
HitTestBehavior.opaque:点击整个区域都会呼应点击事情,可是点击事情不行穿透向下传递,
注释翻译:阻止视觉上坐落其后方的方针接纳事情。  
HitTestBehavior.translucent:同样是点击整个区域都会呼应点击事情,和opaque的差异是点击事情是否能够向下传递,
注释翻译:半透明方针既能够在其范围内承受事情,也能够答应视觉上坐落其后方的方针接纳事情

Flutter ListView怎样翻滚到指定position,列表翻滚原生是怎样的,怎样监听listview翻滚到了哪个Item?假设Item是不固定高度的呢?

Flutter布局束缚规矩是什么姿态的?子类想要多少就要多少吗?进程是怎样样的?

首要,上层 widget 向基层 widget 传递束缚条件;
然后,基层 widget 向上层 widget 传递大小信息。  
最后,上层 widget 决定基层 widget 的方位。
Center(
  child: ConstrainedBox(
    constraints: const BoxConstraints(
      minWidth: 70,
      minHeight: 70,
      maxWidth: 150,
      maxHeight: 150,
    ),
    child: Container(color: red, width: 100, height: 100),
  ),
)

布局束缚

key (兄弟组件仅有)

假设两个小部件的runtimeType和key特点 别离为operator==,则新小部件经过更新底层元素(即,经过运用新小部件调用 Element.update 来替换旧小部件。不然,旧元素从树中移除,新的小部件被胀大成一个元素,新元素被插入到树中。

运用 key 能够操控结构在 widget 重建时与哪些其他 widget 进行匹配。默许状况下,结构依据它们的[`runtimeType`]
以及它们的显示次序来匹配。运用 key 时,结构要求两个 widget 具有相同的和`runtimeType`。
Key 在构建相同类型 widget 的多个实例时很有用。例如,`ShoppingList`widget,
它只构建刚刚好满足的`ShoppingListItem`实例来填充其可见区域:
-   假设没有 key,当时构建中的第一个条目将始终与前一个构建中的第一个条目同步,在语义上,
列表中的第一个条目假设翻滚出屏幕,那么它应该不会再在窗口中可见。
-   经过给列表中的每个条目分配为“语义” key,无限列表能够更高效,由于结构将经过相匹配的语义 key 来同步条目,
并因而具有相似(或相同)的可视外观。此外,语义上同步条目意味着在有状况子 widget 中,保存的状况将附加到相同的语义条目上,而不是附加到相同数字方位上的条目。

全局key

全局仅有

有没有尝试过用Flutter生成web项目,你觉得用flutter来取代前端,目前还有哪方面的问题?

初度加载太慢,首页需求加载很大的文件才能显示出来。

怎样Flutter完结毛玻璃作用

//会对基层一切的子组件起过滤作用
Offstage(
  offstage: !widget.isBlur,
  child: BackdropFilter(
    filter: ImageFilter.blur(sigmaX: 3, sigmaY: 3),
    child: Container(
      width: 200,
      height: 25,
      color: Colors.white24,
    ),
  ),
)

假设现在有一个单词列表页面,需求以混合开发的方式集成进两个App中。他们的文字内容,颜色,字体大小稍有差异。但界面整体共同。你会怎样完结文字,颜色,字体大小这个差异功能?

Flutter 中怎样进行bug捕获与统计?怎样发现线上问题? 自研还需求建立渠道?

flutter 反常捕获与上报

  1. dart同步反常用try catch捕获,异步反常用Flutter的catchError。
//运用try-catch捕获同步反常
try {
  throw StateError('This is a Dart exception');
}catch(e) {
  print(e);
}
  1. 异步反常怎样捕获
//运用catchError捕获异步反常
Future.delayed(Duration(seconds: 1))
    .then((e) => throw StateError('This is a Dart exception in Future.'))
    .catchError((e)=>print(e));
  1. flutter组件反常用下面方式
ErrorWidget.builder = (FlutterErrorDetails flutterErrorDetails){
  //自界说过错提示页面
  return Scaffold(
    body: Center(
      child: Text("Custom Error Widget"),
    )
  );
};
  1. 在没有运用try-catch、catchError句子的状况下,无论是同步反常仍是异步反常,都能够运用Zone直接捕获到。 同时,假设需求会集捕获Flutter运用中未处理的反常,那么能够把main函数中的runApp句子也放置在Zone中,这样就能够在检测到代码运转反常时对捕获的反常信息进行统一处理.

关于Dart中呈现的反常,同步反常运用的是try-catch,异步反常则运用的是catchError。假设想会集办理代码中的一切反常,那么能够Flutter提供的Zone.runZoned()办法。在Dart语言中,Zone表明一个代码履行的环境范围,其概念相似沙盒,不同沙盒之间是互相阻隔的。假设想要处理沙盒中代码履行呈现的反常,能够运用沙盒提供的onError回调函数来拦截那些在代码履行进程中未捕获的反常,如下所示。

//同步抛出反常
runZoned(() {
  throw StateError('This is a Dart exception.');
}, onError: (dynamic e, StackTrace stack) {
  print('Sync error caught by zone');
});
//异步抛出反常
runZoned(() {
  Future.delayed(Duration(seconds: 1))
      .then((e) => throw StateError('This is a Dart exception in Future.'));
}, onError: (dynamic e, StackTrace stack) {
  print('Async error aught by zone');
});
  1. 关于程序中呈现的反常,一般只需求在Flutter运用程序的进口main.dart文件中,运用Flutter提供的FlutterError类会集处理即可,如下所示。
Future<Null> main() async {
  FlutterError.onError = (FlutterErrorDetails details) async {
    Zone.current.handleUncaughtError(details.exception, details.stack);
  };
  runZoned<Future<void>>(() async {
    runApp(MyApp());
  },  onError: (error, stackTrace) async {
    await _reportError(error, stackTrace);
  });
}
Future<Null> _reportError(dynamic error, dynamic stackTrace) async {
  print('catch error='+error);
}

debug状况下

Future<Null> main() async {
  FlutterError.onError = (FlutterErrorDetails details) async {
    if (isDebugMode) {
      FlutterError.dumpErrorToConsole(details);
    } else {
      Zone.current.handleUncaughtError(details.exception, details.stack);
    }
  };
   … //省略其他代码
}
bool get isDebugMode {
  bool inDebugMode = false;
  assert(inDebugMode = true);
  return inDebugMode;
}

Flutter多重嵌套对你代码开发来说有什么影响?查找问题时怎样快速定位某一组件在代码中的方位?