概述

移动开发的方式:混合开发,一套代码,多端运行。

目前比较的成熟的方案是:ReactNative和Flutter,各有优劣,开源社区也都非常活跃。

flutter 调用swift库 flutter调用js库_flutter 调用swift库

                     

flutter 调用swift库 flutter调用js库_ios_02

Flutter 应用产品

flutter 调用swift库 flutter调用js库_ide_03

ReactNative:

flutter 调用swift库 flutter调用js库_ios_04

 实现方式:使用JS代码构建一个跨平台APP,RN 把应用的JS代码(包括依赖的framework)编译成一个js文件,IOS上直接使用内置的javascriptcore, 在Android 则使用webkit.org官方开源的jsc.so来运行js脚本文件。

如果是js 扩展的API, 则直接通过bridge调用native方法;

如果是UI界面, 通过bridge (JS和Nactive 的通信桥梁)把数据传递传递到native , 然后根据数据属性设置各个对应的真实native的View,也就是界面控件会映射原生控件去加载。

缺点:原生控件承载界面渲染,系统升级和api变化会带来不稳定性。

Flutter框架:

flutter 调用swift库 flutter调用js库_ide_05

 Flutter框架包含了:frameWork层是一个UISDK,Engine层有Skia图像渲染引擎和Dart的接口,Embedder 是操作系统适配层。总而言之:flutter 一个纯UI渲染框架;

下面从四个方面分享使用futter实现混合开发的过程:

1、flutter的应用是什么样子,如何构建UI

2、第三方开源框架是否全面

3、flutter如何与原生应用混编

4、如何实现调用系统原生的能力

一、flutter的应用是什么样子,如何构建UI

                                                       

flutter 调用swift库 flutter调用js库_flutter_06

import 'package:flutter/material.dart';
void main() {
  runApp(const MyApp());   //应用入口:main.dart文件下的main函数
}
class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({Key? key, required this.title}) : super(key: key);
  final String title;
  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) { //_counter对象改变,回调build
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text(
              'You have pushed the button this many times:',
            ),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headline4,
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Flutter 界面的核心设计思想便是:一切皆 Widget ,从最顶层的app就是widget,到下面任何的ui元素都可以封装成widget,像客户端常用的视图(View)、视图控制器(View Controller)、活动(Activity)等,在 Flutter 中都是 Widget。

界面的改变通过state设置状态来实现。

Flutter应用通过Dart语言编写:支持运行时编译(JIT)模式,修改代码后可直接热重载。

二:flutter目前的开源库

DartFlutter应用程序的官方软件包存储库:Dart packages

flutter 调用swift库 flutter调用js库_ios_07

 SVGA,RxDart ,HTTP,shared_preferences等等,

使用网络请求数据,加载到列表的常见需求:

pubspec.yaml【flutter应用工程配置文件】导入相关的库


dio: ^3.0.7 //网络请求json_annotation: ^2.4.0 //json


class _SampleAppPageState extends State<SampleAppPage> {
  List widgets = [];
  @override
  void initState() {
    super.initState();
    loadData();
  }
  @override
  Widget build(BuildContext context) {
    return new Scaffold(
        appBar: new AppBar(
          title: new Text("Sample App"),
        ),
        body: new ListView.builder(
            itemCount: widgets.length,
            itemBuilder: (BuildContext context, int position) {
              return Container(
                //内容文字
                child: new Text(" ${widgets[position]["id"]}"
                    + "${widgets[position]["title"]}"),
                //下横线
                decoration: BoxDecoration(border:
                Border(bottom: BorderSide(width: 1, color: Color(0xffe5e5e5)))),
                //边距
                padding: new EdgeInsets.all(10.0),
              );
            }));
  }

  loadData() async {
    String dataURL = "https://jsonplaceholder.typicode.com/posts";
    http.Response response = await http.get(dataURL);
    setState(() {
      widgets = json.decode(response.body);
    });
  }
}

 实现的效果就是如下:

                                               

flutter 调用swift库 flutter调用js库_android_08

三:flutter混编入原生工程

方式:将flutter模块打包成aar,供原生android调用(iOS 使用 pod),三端代码分离;

操作:

a、在安卓app同级目录下可以创建 Flutter 模块:Flutter create -t module flutter_library
b、flutter模块实现功能后打包aar(Flutter build apk --debug)

打包aar的项目结构如下:原生工程导入aar,添加依赖即可使用

                                  

flutter 调用swift库 flutter调用js库_ios_09

四:flutter调用系统原生的能力

Flutter 并没有提供对原生页面操作的方法,所以通过:

在flutter界面打开一个安卓原生界面的流程,查看flutter调用原生系统的方式

1、首先在android应用打开一个flutter界面:

    安卓将flutter界面打包成flutterView加载

public class FlutterPageActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();

        FlutterView flutterView = Flutter.createView(this,getLifecycle(),"defaultRoute");
        setContentView(flutterView);
    }

}

2、flutter应用操作:

    a、打开aroute对应界面 ; 

    b、通过注册方法通道(MethodChannel)的方式打开安卓界面

void main() => runApp(_widgetForRoute(window.defaultRouteName));
const platform = MethodChannel('samples.demo/navigation'); //注册方法通道

Widget _widgetForRoute(String route) {
  switch (route) {
    default: //对应路由类型
      return MaterialApp(
        home:DefaultPage(showBack: true),
      );
  }
}

class DefaultPage extends StatelessWidget {
  DefaultPage({Key key, this.showBack=false }) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("Flutter Default Page"),),
        body: Center(
          child: Column(
            children: <Widget>[
              RaisedButton(
                  child: Text("Go Page A"),
                  //通过注册的方法:openNativePage 点击打开安卓界面
                  onPressed: ()=>platform.invokeMethod('openNativePage') 
              )
            ],
          ),
        )

    );
  }
}

3、android应用实现方法通道,并响应打开界面

public class FlutterPageActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        FlutterView flutterView = Flutter.createView(this,getLifecycle(),"defaultRoute");
       
       //注册方法通道 --方法通道识别:samples.demo/navigation--
        new MethodChannel(flutterView, "samples.demo/navigation").setMethodCallHandler(
                new MethodChannel.MethodCallHandler() {
                    @Override
                    public void onMethodCall(MethodCall call, MethodChannel.Result result){
                        //注册的方法:openNativePage
                        if(call.method.equals("openNativePage")) {
                            //打开安卓页面
                            Intent intent = new Intent(FlutterPageActivity.this, AndroidActivity.class);
                            startActivity(intent);
                            
                            //返回数据给flutter
                            result.success(0);
                        } else {
                            //方法未实现
                        }
                    }
                });
        setContentView(flutterView);
    }
}

以上demo实现了,在安卓项目中混编flutter模块,实现双方调用的功能。

谢谢!