FlutterBoost在Android中的使用

FlutterBoost在Android中的使用

    • FlutterBoost简介
    • 环境要求
    • 集成步骤
      • 1、新建Android工程
      • 2、创建Flutter模块
      • 3、集成FlutterBoost
      • 4、引用Flutter代码
    • 总结

Flutter目前发展越来越火热,在个人理解,Flutter开发现阶段更多情况是用来节约成本,所以想要纯靠Flutter糊口会比较难。但对于公司来说,跨平台+高性能非常符合公司利益,所以掌握Flutter将会大大增加个人竞争力。目前Flutter最多的应用场景是作为一个模块嵌入到原生开发中,闲鱼的FlutterBoost是其中最有代表性的。
本文主要站在对Android和Flutter都有一定了解的角度上,对现有集成FlutterBoost进行混合开发,尽量将集成过程中所遇到的坑都填上。由于Flutter目前更新较快,请注意好开发版本。

FlutterBoost简介

新一代Flutter-Native混合解决方案。 FlutterBoost是一个Flutter插件,它可以轻松地为现有原生应用程序提供Flutter混合集成方案。FlutterBoost的理念是将Flutter像Webview那样来使用。在现有应用程序中同时管理Native页面和Flutter页面并非易事。 FlutterBoost帮你处理页面的映射和跳转,你只需关心页面的名字和参数即可(通常可以是URL)。

FlutterBoostGit传送门:https://github.com/alibaba/flutter_boost

环境要求

  1. Android开发环境 ,本文使用的是Android Studio3.5;
  2. Flutter开发环境 ,本文使用的是Flutter1.5.4(截止2019.09.29,FlutterBoost最新支持到1.5.4);
  3. 最好用真机调试 ,Android模拟器虽然也可以,但是体验会降低;

集成步骤

整个集成步骤,分为两大部分,其一是构建Flutter部分,最终产物是aar包;其二是集成aar包,并初始化flutter。

1、新建Android工程

新建的Android工程作为被接入的原始工程,用于模拟现有的Android项目。注意,FlutterBoost要求API>16,此处我直接选择了19。
FlutterBoost在Android中的使用_第1张图片

2、创建Flutter模块

  1. 项目打开后,在Terminal终端中输入 flutter doctor 检查flutter版本是否为1.5.4,否则在编译过程中将直接报错。
  2. 检查无误后,继续在Terminal中输入cd … 跳转到上级目录,然后运行 flutter create -t module flutter_module 命令创建名为flutter_module的Flutter模块,创建无误则会出现 All done!
    注意不要将模块放在Android项目目录下,因为绝大部分情况Flutter不是专门为了Android写的,在版本控制中会单独开一个仓库。
  3. 添加项目依赖,在setting.gradle结尾处添加如下代码,注意flutter_module路径要与创建的模块相对路径对应。
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        '/flutter_module/.android/include_flutter.groovy'
))
  1. 在app下的build.gradle中添加依赖:
implementation project(':flutter')
  1. ①、点击File->Sync Project with Gradle Files,重新构建Gradle。
    ②、重构完成后,点击Build->Rebuild Project,重新构建项目。
    ③、由于Android Studio3.5默认启用了androidx,所以此步骤定会报错。
    既然要集成flutter,自然是建议将依赖迁移到androidx。
    解决方法是点击Refactor->Migrate to AndroidX,完成自动迁移。中间会有一次弹窗用于备份当前项目,是否备份看个人喜好,如果项目较复杂,则最好备份一遍。点击migrate后,在下方还有一个弹窗,点击Do Refactor,迁移将自动完成。
    ④、打开flutter下的build.gradle,正常情况下会发现依赖中有一处警告报黄,目前最新版本是1.1.0,该版本需要与app的build.gradle保持一致,正常情况下不报黄,保持最新即可(光标指向报黄处,alt+enter/option+enter可提示处最新的版本)。
    ⑤、重新Rebuild Project ,此时仍会有大量报错,此时需要点击错误的文件路径,跳转到有误的文件中,手动删除所有import,文件将自动导入正确的依赖,重复Rebuild和修改依赖,直至Rebuild过程完成。
    ⑥、该过程中可能出现如下错误:
AGPBI: {"kind":"error","text":"Invoke-customs are only supported starting with Android O (--min-api 26)","sources":[{}],"tool":"D8"}

在app的build.gradle中的android标签下,添加如下代码即可解决:

compileOptions {

    sourceCompatibility JavaVersion.VERSION_1_8

    targetCompatibility JavaVersion.VERSION_1_8

}

⑦、在新建的flutter_module中,有一个.android文件夹,用Android Studio打开该项目,重复①——⑤步骤,直至没有错误,关闭此项目。
⑧、在Terminal中,执行cd flutter_module/.android 切换到.android 目录下,执行./gradlew assembleDebug命令,完成依赖加载。

3、集成FlutterBoost

  1. 在Android Studio中,将flutter_module作为一个项目打开,这是一个flutter项目。在pubspec.yaml中添加如下依赖:
  flutter_boost:
    git:
      url: 'https://github.com/alibaba/flutter_boost.git'
      ref: '0.1.54'

然后在Terminal中执行flutter packages get命令拉取依赖。

  1. 在flutter的main.dart中修改代码为:
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';
import 'package:flutter_module/SecondWidget.dart';

import 'FirstWidget.dart';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

//将两个页面注册到FlutterBoost中。
    FlutterBoost.singleton.registerPageBuilders({
      'sample://firstPage': (pageName, params, _) => FirstWidget(),
      'sample://secondPage': (pageName, params, _) => SecondWidget(),
    });
  }

  @override
  Widget build(BuildContext context) => MaterialApp(
      title: 'Flutter Boost example',
      builder: FlutterBoost.init(),

      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("FlutterBoost"),
        ),
        body: new MaterialApp(
          theme: ThemeData(
            primarySwatch: Colors.blue,
          ),
          home: new Container(
            child: new GestureDetector(
              child: new Text("进入第一个页面"),
              onTap: _goFirstpage,
            ),
          ),
        ),
      ));

  void _goFirstpage() {
    setState(() {
    //flutter页面跳转操作
      FlutterBoost.singleton.open("sample://firstPage");
      print("进入第一个页面");
    });
  }
}

  1. 同时建立FirstWidget和SecondWidget文件。
import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';

class FirstWidget extends StatefulWidget {
  @override
  _FirstWidgetState createState() => _FirstWidgetState();
}

class _FirstWidgetState extends State<FirstWidget> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("FlutterBoost FirstWidget"),
        ),
        body: new GestureDetector(
          child: new Container(
            child: new Text("我是第一个页面"),
          ),
          onTap: goSecondPage,
        ),
      ),
    );
  }

  void goSecondPage() {
    FlutterBoost.singleton.open("sample://secondPage");
    print("进入第二个页面");
  }
}

import 'package:flutter/material.dart';
import 'package:flutter_boost/flutter_boost.dart';

class SecondWidget extends StatefulWidget {
  @override
  _SecondWidgetState createState() => _SecondWidgetState();
}

class _SecondWidgetState extends State<SecondWidget> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new Scaffold(
        appBar: new AppBar(
          title: new Text("FlutterBoost"),
        ),
        body: new GestureDetector(
          child: new Container(
            child: new Text("我是第二个页面"),
          ),
          onTap: goFirstPage,
        ),
      ),
    );
  }

  void goFirstPage() {
    FlutterBoost.singleton.open("sample://firstPage");
    print("进入第一个页面");
  }
}

  1. 在原项目中添加依赖并执行File->Sync Project with Gradle Files:
implementation project(':flutter_boost')

至此,FlutterBoost集成完毕。

4、引用Flutter代码

在Android中新建Application,继承与FlutterApplication,在oncreate中初始化Flutter。参考Flutter官方Demo,代码如下:

public class MyApplication extends FlutterApplication {

    @Override
    public void onCreate() {
        super.onCreate();
        FlutterBoost.init(new Platform() {

            @Override
            public Application getApplication() {
                return MyApplication.this;
            }

            @Override
            public boolean isDebug() {
                return true;
            }

            @Override
            public void openContainer(Context context, String url, Map<String, Object> urlParams, int requestCode, Map<String, Object> exts) {
                PageRouter.openPageByUrl(context, url, urlParams, requestCode);
            }

            @Override
            public IFlutterEngineProvider engineProvider() {
                return new BoostEngineProvider() {
                    @Override
                    public BoostFlutterEngine createEngine(Context context) {
                        return new BoostFlutterEngine(context, new DartExecutor.DartEntrypoint(
                                context.getResources().getAssets(),
                                FlutterMain.findAppBundlePath(context),
                                "main"), "/");
                    }
                };
            }

            @Override
            public int whenEngineStart() {
                return ANY_ACTIVITY_CREATED;
            }
        });

    }
}

官方采用PageRouter作为统一调用入口,因此新建PageRoute工具类,参数、Url等可自行定义:

public class PageRouter {

    public static final String FLUTTER_PAGE_MAIN = "sample://firstPage";

    public static boolean openPageByUrl(Context context, String url, Map params) {
        return openPageByUrl(context, url, params, 0);
    }

    public static boolean openPageByUrl(Context context, String url, Map params, int requestCode) {
        try {
            Intent intent = new Intent(context, FlutterPageActivity.class);
            intent.putExtra("url", url);
            context.startActivity(intent);
            return true;
        } catch (Throwable t) {
            return false;
        }
    }
}

在Android原生代码中,想要跳转Flutter代码如下:

PageRouter.openPageByUrl(MainActivity.this, PageRouter.FLUTTER_PAGE_MAIN, new HashMap());

至此集成全部完成。

总结

FlutterBoost方式进行混合开发,侵入性低,是闲鱼方案相对于其他Flutter混合开发最大的优点,能够很好公司现有项目开发的需要,也适合中小公司节约成本,安全稳定的需要。

原项目仍是原项目,仅仅是添加了Flutter依赖。
在project视图模式下,android->build->outputs->aar下有aar包,可作为FlutterBoost的依赖包用于其他项目。
flutter_module是新的Flutter依赖,可以单独打开用于开发Flutter代码。
flutter_module下的.android是Flutter代码的Android模块,单独打开后运行Rebuild可在Flutter->build->outputs->aar中得到aar依赖,用于导出到别的项目进行代码复用。

实际开发中,对Flutter模块的开发也像本案例一样,在一个全新项目中开发,集成生成出来的aar作为单独依赖加入到原有项目中。这种方式对原项目甚至不用任何改动。

参考资料:
https://blog.csdn.net/lizubing1992/article/details/90760406
https://github.com/alibaba/flutter_boost/blob/master/README_CN.md
https://www.jianshu.com/p/4eee4ddb2b6a
https://www.cnblogs.com/hupo376787/p/10563454.html
https://blog.csdn.net/zzh_receive/article/details/81168500

原创作品,转载请注明 Author:Kukugtu。

你可能感兴趣的:(Flutter)