Flutter核心技术与实战
陈航
美团点评高级技术专家
立即订阅
6150 人已学习
课程目录
已完结 47 讲
0/4登录后,你可以任选4讲全文学习。
课前必读 (3讲)
开篇词 | 为什么每一位大前端从业者都应该学习Flutter?
免费
01 | 预习篇 · 从0开始搭建Flutter工程环境
02 | 预习篇 · Dart语言概览
Flutter开发起步 (3讲)
03 | 深入理解跨平台方案的历史发展逻辑
04 | Flutter区别于其他方案的关键技术是什么?
05 | 从标准模板入手,体会Flutter代码是如何运行在原生系统上的
Dart语言基础 (3讲)
06 | 基础语法与类型变量:Dart是如何表示信息的?
07 | 函数、类与运算符:Dart是如何处理信息的?
08 | 综合案例:掌握Dart核心特性
Flutter基础 (13讲)
09 | Widget,构建Flutter界面的基石
10 | Widget中的State到底是什么?
11 | 提到生命周期,我们是在说什么?
12 | 经典控件(一):文本、图片和按钮在Flutter中怎么用?
13 | 经典控件(二):UITableView/ListView在Flutter中是什么?
14 | 经典布局:如何定义子控件在父容器中排版的位置?
15 | 组合与自绘,我该选用何种方式自定义Widget?
16 | 从夜间模式说起,如何定制不同风格的App主题?
17 | 依赖管理(一):图片、配置和字体在Flutter中怎么用?
18 | 依赖管理(二):第三方组件库在Flutter中要如何管理?
19 | 用户交互事件该如何响应?
20 | 关于跨组件传递数据,你只需要记住这三招
21 | 路由与导航,Flutter是这样实现页面切换的
Flutter进阶 (17讲)
22 | 如何构造炫酷的动画效果?
23 | 单线程模型怎么保证UI运行流畅?
24 | HTTP网络编程与JSON解析
25 | 本地存储与数据库的使用和优化
26 | 如何在Dart层兼容Android/iOS平台特定实现?(一)
27 | 如何在Dart层兼容Android/iOS平台特定实现?(二)
28 | 如何在原生应用中混编Flutter工程?
29 | 混合开发,该用何种方案管理导航栈?
30 | 为什么需要做状态管理,怎么做?
31 | 如何实现原生推送能力?
32 | 适配国际化,除了多语言我们还需要注意什么?
33 | 如何适配不同分辨率的手机屏幕?
34 | 如何理解Flutter的编译模式?
35 | Hot Reload是怎么做到的?
36 | 如何通过工具链优化开发调试效率?
37 | 如何检测并优化Flutter App的整体性能表现?
38 | 如何通过自动化测试提高交付质量?
Flutter综合应用 (6讲)
39 | 线上出现问题,该如何做好异常捕获与信息采集?
40 | 衡量Flutter App线上质量,我们需要关注这三个指标
41 | 组件化和平台化,该如何组织合理稳定的Flutter工程结构?
42 | 如何构建高效的Flutter App打包发布环境?
43 | 如何构建自己的Flutter混合开发框架(一)?
44 | 如何构建自己的Flutter混合开发框架(二)?
结束语 (1讲)
结束语 | 勿畏难,勿轻略
特别放送 (1讲)
特别放送 | 温故而知新,与你说说专栏的那些思考题
Flutter核心技术与实战
登录|注册

26 | 如何在Dart层兼容Android/iOS平台特定实现?(一)

陈航 2019-08-27
你好,我是陈航。
在上一篇文章中,我与你介绍了在 Flutter 中实现数据持久化的三种方式,即文件、SharedPreferences 与数据库。
其中,文件适用于字符串或者二进制流的数据持久化,我们可以根据访问频次,决定将它存在临时目录或是文档目录。而 SharedPreferences 则适用于存储小型键值对信息,可以应对一些轻量配置缓存的场景。数据库则适用于频繁变化的、结构化的对象存取,可以轻松应对数据的增删改查。
依托于与 Skia 的深度定制及优化,Flutter 给我们提供了很多关于渲染的控制和支持,能够实现绝对的跨平台应用层渲染一致性。但对于一个应用而言,除了应用层视觉显示和对应的交互逻辑处理之外,有时还需要原生操作系统(Android、iOS)提供的底层能力支持。比如,我们前面提到的数据持久化,以及推送、摄像头硬件调用等。
由于 Flutter 只接管了应用渲染层,因此这些系统底层能力是无法在 Flutter 框架内提供支持的;而另一方面,Flutter 还是一个相对年轻的生态,因此原生开发中一些相对成熟的 Java、C++ 或 Objective-C 代码库,比如图片处理、音视频编解码等,可能在 Flutter 中还没有相关实现。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《Flutter核心技术与实战》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(11)

  • 矮个子先生😝
    看了下Flutter提供的api,动手实现了下,native调flutter的方法
    Future<String> nativeCallFlutter(int a) async {
      print('success $a');
      return 'success';
    }

    platform.setMethodCallHandler((MethodCall call) async {
        if (call.method == 'nativeCallFlutter') {
         return await nativeCallFlutter(call.arguments);
        }
        return 'none';
      });

    在iOS端调用:
    [channel invokeMethod:@"nativeCallFlutter" arguments:@1 result:^(id _Nullable result) {
            NSLog(@"result = %@",result);
        }];

    作者回复: 赞,方法通道是双向的,既支持Dart调Native,也支持Native调Dart。第31节会讲具体的实践

    2019-08-27
    2
  • 寂寞不点烟
    而原生代码在处理方法调用请求时,如果涉及到异步或非主线程切换,需要确保回调过程是在原生系统的 UI 线程(也就是 Android 和 iOS 的主线程)。在Android中UI现线程不一定是主线程。
    2019-12-10
    1
  • 菜头
    如果是获取系统相册直接获取 图片对象
    Dart 支持各个平台的 image 对象类型吗

    作者回复: 这种建议只在原生实现界面,flutter接受最后选择的图片地址

    2019-11-03
  • 和小胖
    思考题:
    flutter 端:
    // 处理按钮点击
    handleButtonClick() async {
      int result;
      // 异常捕获
      try {
        // 异步等待方法通道的调用结果
        result = await platform.invokeMethod('openAppMarket', <String, dynamic>{
          'appId': "com.xxx.xxx",
          'packageName': "xxx.com.xxx",
        });
      } catch (e) {
        result = -1;
      }
      print("Result:$result");
    }

    Android 端:
    if (call.method == "openAppMarket") {
                        if (call.hasArgument("appId")) {
                            //获取 appId
                            call.argument<String>("appId")
                        }
                        if (call.hasArgument("packageName")) {
                            //获取包名
                            call.argument<String>("packageName")
                        }
                    }

    作者回复: 厉害👍

    2019-10-14
  • 辉哥
    问一下,Flutter和原生应用应该不处于同一个进程吧

    作者回复: 不特殊处理的话,是一个进程

    2019-09-24
  • 江宁彭于晏
    // 声明 MethodChannel
    const platform = MethodChannel('samples.chenhang/utils');

    // 处理按钮点击
    handleButtonClick(Map paramDic) async{
      int result;
      // 异常捕获
      try {
        // 异步等待方法通道的调用结果,Map 中插入appid和包名,跳转链接等信息
        result = await platform.invokeMethod('openAppMarket', [paramDic]);
      }
      catch (e) {
        result = -1;
      }
      print("Result:$result");
    }

    作者回复: 这个接口的易用性貌似不太合理啊,调用方和原生代码宿主对于参数的处理都比较别扭

    2019-09-11
  • 小水滴
    iOS系统创建多份FlutterViewController会有什么问题吗

    作者回复: 每启动一个 FlutterVC实例,就会创建一套新的渲染机制,即 Flutter Engine,以及底层的 Isolate。这些实例之间的内存是不互相共享的,系统资源消耗比较大

    2019-08-30
  • ptlCoder
    methodChannelWithName:@"samples.chenhang/utils"
    这个通道名称有什么要求嘛?还是说见名知意就好?
    另外,如果flutter很多地方都用到了原生系统方法,岂不是在iOS或安卓flutter入口那做很多个判断?

    作者回复: 1.没要求,主要Dart层与原生宿主层保持一致就可以;
    2.对

    2019-08-29
  • 许童童
    dart层通过platform.invokeMethod 第二个参数传入动态参数
    native层可以通过call.argument拿到参数

    作者回复: 赞

    2019-08-27
  • dart层:
    platform.invokeMethod('openAppStore', {"appId": "com.tencent.mm"});

    native层:
    String appId = call.argument("appId");
                                try {
                                    Uri uri = Uri.parse("market://details?id=" + appId);
                                    Intent intent = new Intent(Intent.ACTION_VIEW, uri);
                                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                                    startActivity(intent);
                                } catch (Exception e) {
                                    result.error("UNAVAILABLE", "没有安装应用市场", null);
                                }

    作者回复: 赞

    2019-08-27
  • yasuoyuhao
    調用原生能力使得 flutter 如虎添翼,並不是要完全取代原生開發,而是採取共生共存的概念。利用原生龐大的生態系,第三方開源組件,為初生的 flutter 提供了擴充,原生調用的功能。使得很多原生開源組件的解決方案可以很好的引入 flutter,這是喜歡 flutter 的其中一個原因。
    2019-08-27
收起评论
11
返回
顶部