Flutter 混合开发FlutterBoost Android 端接入流程

栏目: Android · 发布时间: 5年前

内容简介:最近公司开始推行使用Flutter用于移动端开发,忙活了一个多月的Flutter混合开发迭代端午节后准备上线,写下此过程的坑以及一些接入流程,以及Flutter技术。由于我主业是搞Android开发的,iOS还是个菜鸟,先介绍一下Android混合接入流程很多情况下,Flutter的接入都是在原有的移动端项目的基础上接入,这样相对于侵入原有项目弱,并且接入的成本低,风险也低。

最近公司开始推行使用Flutter用于移动端开发,忙活了一个多月的Flutter混合开发迭代端午节后准备上线,写下此过程的坑以及一些接入流程,以及Flutter技术。

由于我主业是搞Android开发的,iOS还是个菜鸟,先介绍一下Android混合接入流程

1.创建Flutter module

很多情况下,Flutter的接入都是在原有的移动端项目的基础上接入,这样相对于侵入原有项目弱,并且接入的成本低,风险也低。

flutter create -t module flutter_module
复制代码

在命令行界面录入即可,最好是和原本的项目在相同的目录下,同级文件夹。我的项目基本是原有项目是一个git仓库,对应的Flutter代码是在另一个git仓库,这样版本管理也是比较好的

2.Android 开始接入

在原有setting.gradle文件末尾的添加一下代码

setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        '/flutter_module/.android/include_flutter.groovy'
))
复制代码

这样就会引入到对应的Flutter的module资源,对应的编译脚本,Flutter框架已经写好,后续有时间可以读读

在app目录下的build.gradle文件中添加Flutter依赖

implementation project(':flutter')
复制代码

主要的依赖链如下

flutter_module/.android/include_flutter.groovy ->
flutter_module/.android/Flutter/build.gradle ->
$flutterRoot/packages/flutter_tools/gradle/flutter.gradle 
复制代码

很方便的完成混合开发的打包操作,接入完之后最好在flutter项目下面的.android文件下,用命令行 工具 执行以下

gradlew assembleDebug
复制代码

命令完成对应的Android依赖加载

3.原生显示Flutter的视图

Button open = findViewById(R.id.openBtn);
open.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Intent intent = new Intent();
        intent.setClass(MainActivity.this, MyFlutterActivity.class);
        startActivity(intent);
    }
});

public class MyFlutterActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_flutter);
        final FlutterView flutterView = Flutter.createView(
                this,
                getLifecycle(),
                "route1"
        );
        final FrameLayout layout = findViewById(R.id.flutter_container);
        layout.addView(flutterView);
    
    }
}
复制代码

只需要在Activity中的addView即可,看起来很简单,不过存在很多问题,跳转过程可能会有黑屏情况,以及Flutter视图的复用也是个问题,以及对应的Flutter 跳转Native界面也是个问题。于是乎谷歌发现FlutterBoost框架解决了大部分以上的问题。

4.FlutterBoost框架的接入

依照 github.com/alibaba/flu… 官方的文档,接入发现有很多的坑,不知道是不是开发人员都反感写文档一样的。

接入的流程如下:

4.1 Flutter项目接入FlutterBoost

在对应的pubspec.yaml文件中加入依赖,pubspec.yaml就是一个配置文件。

flutter_boost:
        git:
            url: 'https://github.com/alibaba/flutter_boost.git'
            ref: '0.0.411'
复制代码

之后调用Package get,右上角即可查看,之后还是在.android 文件下执行 gradlew assembleDebug,完成依赖下载。

4.2 Flutter中main.dart文件中配置

@override
  void initState() {
    super.initState();
    FlutterBoost.singleton.registerPageBuilders({
        //对应的Page的名字,最好是类Http格式
      'demoPage': (pageName, params, _) {
        return DemoPage();
      },
    });
    FlutterBoost.handleOnStartPage();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'Flutter Boost example',
        builder: FlutterBoost.init(postPush: _onRoutePushed),
        home: Container());
  }
 void _onRoutePushed(
  String pageName, String uniqueId, Map params, Route route, Future _) {}

复制代码

4.3 Android 中的Application的设置

@Override
  public void onCreate() {
    super.onCreate();
    initFlutterBoot();
  }

  private void initFlutterBoot() {
    FlutterBoostPlugin.init(new IPlatform() {
      @Override
      public Application getApplication() {
        return mApplication;
      }


      @Override
      public Activity getMainActivity () {
        //这里返回null,可以避免跳转界面的(MainActivity)的页面整体上移
        return null;
      }

      @Override
      public boolean isDebug() {
        return AppConfig.IS_DEVELOPING;
      }


      @Override
      public boolean startActivity(Context context, String url, int requestCode) {
        //Flutter 跳转的回调
        return PageRouter.openPageByUrl(context,url,requestCode);
      }

      @Override
      public Map getSettings() {
        return null;
      }
    });
  }
复制代码

坑1:getMainActivity 如果返回MainActivity,会导致对应的主页面的布局整体上移,发现给null也没啥问题。

4.4 Native和Flutter界面的跳转

Native-->Fluuter

可以使用官方Demo中的PageRouter

public class PageRouter {

  public static final String COMMISSION_TASK_PAGE = "gamma://flutter/commissionTaskPage";
  public static final String NATIVE_CUST_INFO_PAGE_URL = "gamma://native/custInfo";

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

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

  public static boolean openPageByUrl(Context context, String url, int requestCode) {
    return openPageByUrl(context, url, requestCode, "{}");
  }

  public static boolean openPageByUrl(Context context, String url, int requestCode, String json) {
    try {
      if (url.startsWith(COMMISSION_TASK_PAGE)) {
        //贷后任务
        Intent intent = new Intent(context, FlutterPageActivity.class);
        intent.putExtra("pageName", "gamma://flutter/commissionTaskPage");
        intent.putExtra("json", json);
        context.startActivity(intent);
        return true;
      } else if (url.contains(NATIVE_CUST_INFO_PAGE_URL)) {
        //打开客户界面
        Map<String, String> params = getUrlParams(url);
          AppUIHelper
              .showCustomerInfoActivity(context, params.get("custId"));
        return true;
      }
    } catch (Throwable t) {
      return false;
    }
  }
//获取对应url中的参数
  private static Map getUrlParams(String url) {
    Map<String, Object> map = new HashMap<>();
    url = url.replace("?", ";");
    if (!url.contains(";")) {
      return map;
    }
    if (url.split(";").length > 0) {
      String[] arr = url.split(";")[1].split("&");
      for (String s : arr) {
        String key = s.split("=")[0];
        String value = s.split("=")[1];
        map.put(key, value);
      }
      return map;

    } else {
      return map;
    }
  }
}

复制代码

这样相对于好管理,Native页面可以设置以Native开头,Flutter以flutter开头,这样好区分。

对应的FlutterPageActivity可以根据官方Demo自行修改。

坑2:FlutterPageActivity中最好加上以下代码

@Override
  protected void onCreate(Bundle savedInstanceState) {
    FlutterMain.startInitialization(this);
    super.onCreate(savedInstanceState);
  }
复制代码

不然会运行报错

Flutter -- >Native

这种类型跳转和Activity之间互相跳转有点类似

FlutterBoost.singleton.openPage(
        "${NativeUrl.NATIVE_CUST_INFO}?custId=${custId};",
        {});
复制代码

这中类型的跳转会回调到前面Application中的 FlutterBoostPlugin.init 方法中的startActivity方法中,只会在用PageRouter来接收即可。 之后自行做界面的跳转


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

精通Git(第2版)

精通Git(第2版)

Scott Chacon、Ben Straub / 门佳、刘梓懿 / 人民邮电出版社 / 2017-9 / 89.00元

Git 仅用了几年时间就一跃成为了几乎一统商业及开源领域的版本控制系统。本书全面介绍Git 进行版本管理的基础和进阶知识。全书共10 章,内容由浅入深,展现了普通程序员和项目经理如何有效利用Git提高工作效率,掌握分支概念,灵活地将Git 用于服务器和分布式工作流,如何将开发项目迁移到Git,以及如何高效利用GitHub。一起来看看 《精通Git(第2版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码