Flutter学习笔记

Flutter笔记

UI框架

Widget

widgets类似于Android中的view,它比view更加过分,flutter所有的东西都是由widgets组成。

看这个就很好理解了。

在Android中,Activity一般用于管理view的生命周期,处理流程,在flutter中提供了类似的widget:

  • StatelessWidget
  • StatefulWidget

主要通过重写build方法实现对子widget的加载

俩类widget区别在于调用build方法时机不同.在 Flutter 中每个页面都是一帧。无状态就是保持在那一帧。而有状态的 Widget 当数据更新时,其实是绘制了新的 Widget,只是 State 实现了跨帧的数据同步保存。

可以这么理解,statefulwidget通过state对象对外提供修改的支持
在这里插入图片描述

在这里插入图片描述

通用widget:

  • Container: Container 可让您创建矩形视觉元素。container 可以装饰为一个BoxDecoration, 如 background、一个边框、或者一个阴影。 Container 也可以具有边距(margins)、填充(padding)和应用于其大小的约束(constraints)。另外, Container可以使用矩阵在三维空间中对其进行变换。
  • Text:该 widget 可让创建一个带格式的文本
  • Row、 Column: 这些具有弹性空间的布局类Widget可在水平(Row)和垂直(Column)方向上创建灵活的布局。其设计是基于web开发中的Flexbox布局模型。
  • Stack: 取代线性布局 (和Android中的LinearLayout相似),Stack允许子 widget 堆叠, 你可以使用 Positioned 来定位他们相对于Stack的上下左右四条边的位置。Stacks是基于Web开发中的绝度定位(absolute positioning )布局模型设计的。

匿名函数

GestureDetector(
          // ignore: named_function_expression
          onTap:(){
          },
           ...
           )

dart语法支持以函数作为参数,我们直接传入我们想要实现的函数,当底层响应监听时,调用我们传入的函数即可,原理很简单。

final GestureTapCallback onTap;
	typedef GestureTapCallback = void Function();
	if (recognizer.onTap != null)
	      recognizer.onTap();

调用Android代码

为了调用Android代码,在Android oncreate()方法中

	new MethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(new MethodChannel.MethodCallHandler() {
	            @Override
	            public void onMethodCall(MethodCall methodCall, MethodChannel.Result result) {
	
	                if (methodCall.equals("getDeviceId")) {
	                    result.success(id);
	                }
	            }
	        });

Flutter中

class JavaCall{
  static const platform = const MethodChannel('samples.flutter.io/test');
  static getResult() async {
    String result=await platform.invokeMethod("getDeviceId");
    print(result);
  }
}

保证CHANNEL是一致的。

异步

刚刚调用Android代码这里引出了dart语言的一个特性:异步支持 与java提供多线程不同,dart本身就是单线程的,所以没有与多线程相关的概念,但是单线程肯定不能满足需要,所以dart提出了异步的支持,这就是 async await Future

static  getResult() async {
	    print("异步执行前");
	    String result=await platform.invokeMethod("getDeviceId");
	    print("异步执行后");
	    return result;
	  }

使用async关键字修饰这个函数 说明这个函数是一个异步函数

在异步函数中使用await 代表该操作是一个耗时操作,无需等待继续执行

异步函数的返回值是一个Future类型的对象。我这里的代码虽然返回的是String,但是会直接封装成Future。必须返回的是Future类型。通过流式响应可以处理异步操作,比如:

      print("顺序执行前");
      JavaCall.getResult().then((onValue){
        print("异步执行then");
        for(int i=1;i<=20;i++){
          map["t$i"]=((20+i).toString()+onValue);
        }
        itemStatefull.update();
      }
      );
     itemStatefull=new RecordBodyItemStatefull(map);
     print("顺序执行后");	

这里代码合起来就是,由于flutter调用java代码存在阻塞可能,所以需要使用异步调用。异步执行调用java代码,在调用完成后,根据获取的String信息刷新页面,整个执行顺序是:

info flutter.tools I/flutter (28853): 顺序执行前

info flutter.tools I/flutter (28853): 异步执行前

info flutter.tools I/flutter (28853): 顺序执行后

info flutter.tools I/flutter (28853): 异步执行后

info flutter.tools I/flutter (28853): 异步执行then

这个特性来源于消息循环队列

一个Dart应用有一个消息循环和两个消息队列-- event队列和microtask队列。

event队列包含所有外来的事件:I/O,mouse events,drawing events,timers,isolate之间的message等。

microtask 队列在Dart中是必要的,因为有时候事件处理想要在稍后完成一些任务但又希望是在执行下一个事件消息之前。

说明了dart的运行机制,虽然dart是单线程,但是还是有异步的操作,所以整个流程是执行main操作,执行两个队列中的操作

编译原理

能力不够,对于flutter的跨平台和优越性没有一点感觉。下面两个博客讲解了flutter原理

https://blog.csdn.net/alitech2017/article/details/80937091

https://www.jianshu.com/p/ebbd7a68936a

两点

  • flutter不是使用标准Web技术,而是借助可移植的图形加速渲染引擎、高性能的本地ARM代码,并以此实现跨设备、跨平台的高质量用户体验。

  • 区别于比较更新,flutter控件树中的控件直接通过可移植的图形加速渲染引擎、高性能的本地ARM代码进行绘制,不再需要通过虚拟DOM或虚拟控件、真实DOM或平台控件这些中间对象来绘制

感想

flutter的坑还比较多,比如我重新编译时还会出现页面没有更新的情况,检查了半天,多试几次就正常了。还有其他的坑。调试界面不友好 。包体积也过大,这是目前无法忽视的问题

https://flutter-app-in-action.netlify.com/#/docs/第一章/Dart 基础

反编译

通过反编译,我们发现dart代码并不在dex文件中,而是在assests目录下
在这里插入图片描述

isolate_snapshot_data:用于加速 isolate 启动,业务无关代码,固定,仅和 flutter engine 版本有关;

vm_snapshot_data: 用于加速 Dart VM 启动的产物,业务无关代码,仅和 flutter engine 版本有关;

platform.dill:和 Dart VM 相关的 kernel 代码,仅和 Dart 版本以及 engine 编译版本有关。固定,业务无关代码;

kernel_blob.bin:业务代码产物

如果是发布包中不会看到kernel_blob.bin。

在这里插入图片描述
在这里插入图片描述

是不是可以这么理解,我们写的dart文件代码都被转成了二进制文件,通过类似动态代码加载技术的方式完成了代码加载,二进制代码与平台无关,所以也不需要虚拟机将其转化为中间代码。

参考

https://www.jianshu.com/p/f44db0d088e5
https://blog.csdn.net/alitech2017/article/details/80937091
https://www.jianshu.com/p/ebbd7a68936a

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值