请稍侯

iOS问题汇总之iOS应用 - Flutter混合开发关键点

09 September 2020

iOS问题汇总之iOS应用 - Flutter混合开发关键点

Flutter 要点

Flutter常用依赖

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter

  # The following adds the Cupertino Icons font to your application.
  # Use with the CupertinoIcons class for iOS style icons.
  cupertino_icons: ^0.1.2
  english_words: ^3.1.0
  fluro: "^1.5.1"
  flutter_webview_plugin: ^0.3.5
  # Flutter 常用工具类库 https://github.com/Sky24n/flustars
  flustars: 0.2.6+1
  # 格式化String https://github.com/Naddiseo/dart-sprintf
  sprintf: ^4.0.2
  flutter_swiper: ^1.1.6
  # Toast插件 https://github.com/OpenFlutter/flutter_oktoast
  oktoast: ^2.2.1
  # Dart 常用工具类库 https://github.com/Sky24n/common_utils
  common_utils: ^1.1.3
  # 网络库 https://github.com/flutterchina/dio

  dio: ^3.0.7
  # https://github.com/ReactiveX/rxdart
  rxdart: ^0.22.5
  event_bus: ^1.0.1
  # UI库 https://flui.xin/guide.html
  flui: 0.7.4
  provider: ^3.2.0
  # 验证码框 https://github.com/adar2378/pin_code_fields
  pin_code_fields: ^2.3.0+3
dev_dependencies:
  flutter_test:
    sdk: flutter

Native端关键步骤
FlutterEngine 与 FlutterMethodChannel

//定义engine 与 methodChannel
FlutterEngine *flutterEngine = [[FlutterEngine alloc] initWithName:@"test engine"];
FlutterMethodChannel *commonChannel = [FlutterMethodChannel methodChannelWithName:@"native_common_channel" binaryMessenger:self.flutterEngine];
[self.flutterEngine run];

//定义handler
NSMutableDictionary <NSString *, FlutterMethodCallHandler>* handlers = @{};
FlutterMethodCallHandler handler = ^(FlutterMethodCall *call, FlutterResult result) {
        NSMutableDictionary * userInfo = @{@"name":"zhangsan",@"age":@"30"};
        NSString * json = [userInfo mj_JSONString];
        result(json);
} 
handlers[@"test_native"] = handler;

//为channer设置methodCallHandler
commonChannel.methodCallHandler = ^(FlutterMethodCall *call, FlutterResult result) {
            FlutterMethodCallHandler handler = [weakSelf.handlers objectForKey:call.method];
            if (handler) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    handler(call, result);
                });
            }
};

Flutter ViewController 需要从 FlutterViewController 继承下来

@interface LWFlutterVC:FlutterViewController  @end

LWFlutterVC *flutterViewController = [[LWFlutterVC alloc] initWithEngine:self.flutterEngine nibName:nil bundle:nil];

如果是Flutter与Native混合项目,iOS端的podfile添加这样的设置:

flutter_application_path = File.expand_path('../.') + '/Flutter_DemoModule'
load File.join(flutter_application_path, '.ios', 'Flutter', 'podhelper.rb')

target 'App_ios' do
    # Pods for App
    install_all_flutter_pods(flutter_application_path)
    pod 'Masonry', '~> 1.1.0'
end

Flutter端重点
程序入口

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

StatefulWidget

class MyApp extends StatefulWidget {
  MyApp(){
    final router = new Router();
    Routes.configureRoutes(router);
    Application.router = router;
  }
  @override
  State<StatefulWidget> createState() {
    // TODO: implement createState
    return new _MyAppState();
  }
}

class _MyAppState extends State<MyApp>{
  bool _hasLogin = false;
  _MyAppState(){
    _hasLogin = true;
  }
  showWelcomePage(){
    if (_hasLogin == true){
//      return SplashPage();
      return MyHomePage();
    }
    else{
      return null;
    }
  }
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return FLToastProvider(
      defaults: ToastPV.toastDefaults,
      child: MaterialApp(
        title: 'titles',
        theme: new ThemeData(
          primaryColor: Colours.app_main,
          backgroundColor: Color(0xFFEFEFEF),
          accentColor: Color(0xFF888888),
          textTheme: TextTheme(
            //设置Material的默认字体样式
            body1: TextStyle(color: Color(0xFF888888), fontSize: 16.0),
          ),
          iconTheme: IconThemeData(
            color: Colours.app_main,
            size: 35.0,
          ),
        ),
        home: new Scaffold(body: showWelcomePage(),),
        onGenerateRoute: Application.router.generator,
      ),
    );
  }
}

StatelessWidget

class MyApp extends StatelessWidget {                
  @override                
  Widget build(BuildContext context) {                
    final wordPair = WordPair.random();                
    return MaterialApp(                
      title: 'Welcome to Flutter',                
      home: Scaffold(                      
          title: Text('Welcome to Flutter'),                
        ),                
        body: Center(                
          child: Text(wordPair.asPascalCase),                
          child: RandomWords(),                
        ),                
      ),                
    );                
  }

Dart 要点

JIT 与 AOT
Dart 是少数同时支持 JIT(Just In Time,即时编译)和 AOT(Ahead of Time,运行前编译)的语言之一。

内存分配与垃圾回收
Dart VM 的内存分配策略比较简单,创建对象时只需要在堆上移动指针,内存增长始终是线性的,省去了查找可用内存的过程;
在 Dart 中,并发是通过 Isolate实现的,一秀配合事件循环(Event Looper)在事件队列(Event Queue)上传递消息通信。Isolate 是类似于线程但不共享内存,独立运行的 worker。这样的机制,就可以让 Dart 实现无锁的快速分配。

单线程模型
支持并发执行线程的高级语言(比如,C++、Java、Objective-C),大都以抢占式的方式切换线程,即:每个线程都会被分配一个固定的时间片来执行,超过了时间片后线程上下文将被抢占后切换。如果这时更在更新线程间的共享资源,抢占后就可能导致数据不同步的问题。解决这个问题的方式,使用锁来保护共享资源,但锁本身又可能会带来性能损耗,甚至出现死锁;

Dart 是单线程模型,因为它天然不存在资源竞争和状态同步的问题。这就意味着,一旦某个函数开始执行,就将执行到这个函数结束,而不会被其他 Dart 代码打断。所以 Dart 中并没有线程,只有 Isolate(隔离区)。Isolate之间不会共享内存,就像几个运行在不同进程中的 worker,通过事件循环(Event Looper)在事件队列(Event Queue)上传递消息通信。

类型安全
Dart是类型安全的语言,支持静态类型检测,可以在编译前发现一些类型的错误,并排除潜在问题。另外Dart还有似类ruby mixin混入其他功能实现类似多继承的特性。