Flutter混合开发:Android中如何启动Flutter

简介: flutter可以独立完成项目,但是在现有项目情况下最好的方式就是混合开发,逐步过渡。这样就会共存native和flutter代码,而其中最关键的就是native如何启动flutter页面,及flutter与native如何交互。本文以Android为例,展示如何在一个现有项目中引入flutter、启动flutter,如何加速启动以及如何传参。

现有项目中引入Flutter


在现有的Android项目中,新建一个flutter module。创建完module后会发现自动在主module中依赖了。当然我们如果其他项目使用该flutter模块,并不会自动进行这一步,所以要先在setting.gradle中注册,如下:

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


然后在主module中依赖:

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


这样就可以进行混合开发了。


启动flutter页面


新建flutter module后会自动创建一个main页面,那么native如何打开这个页面?

首先在主module的manifest中添加:

<activity
           android:name="io.flutter.embedding.android.FlutterActivity"
           android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
           android:hardwareAccelerated="true"
           android:windowSoftInputMode="adjustResize"
           />
复制代码


然后用一下代码即可打开flutter主页面


startActivity(FlutterActivity.createDefaultIntent(this))
复制代码


那么如何打开其他页面?

比如我们创建一个新的flutter页面second:


import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SecondPage extends StatefulWidget{
  @override
  State<StatefulWidget> createState() {
    return _SecondPage();
  }
}
class _SecondPage extends State<SecondPage>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("test"),
        ),
        body:Text("test")
    );
  }
}
复制代码


然后在main.dart的App下注册这个页面:


class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
      routes: {
        "second" : (BuildContext context) => SecondPage(),  //也可以用其他方式注册
      },
    );
  }
}
复制代码


这样在flutter中可以用以下代码打开这个页面:


Navigator.of(context).pushNamed("second");
复制代码


而在Android中就可以用以下代码即可打开该页面:


startActivity(FlutterActivity.withNewEngine().initialRoute("second").build(this))
复制代码


加速启动


通过上面代码打开flutter页面时会出现黑屏现象,时间并不短,很影响体验。因为每次都重新new一个flutter engine( createDefaultIntent函数内部其实也是withNewEngine().build(launchContext) )。

官方给出的解决方案是使用engine cache,比如在Appliation中添加cache:


var flutterEngine = FlutterEngine(this)
        flutterEngine.dartExecutor.executeDartEntrypoint(
                DartExecutor.DartEntrypoint.createDefault()
        )
        FlutterEngineCache.getInstance().put("main", flutterEngine)
复制代码


然后将启动改成:


startActivity(FlutterActivity.withCachedEngine("main").build(this))
复制代码


但是上面仅仅是启动main页面,如果想启动其他页面,比如second,就需要继续添加cache:


var flutterEngine2 = FlutterEngine(this)
        flutterEngine2.navigationChannel.setInitialRoute("second")
        flutterEngine2.dartExecutor.executeDartEntrypoint(
                DartExecutor.DartEntrypoint.createDefault()
        )
        FlutterEngineCache.getInstance().put("second", flutterEngine2)
复制代码


注意这里通过setInitialRoute设置了route。然后启动即可:


startActivity(FlutterActivity.withCachedEngine("second").build(this))
复制代码


通过缓存engine,启动时黑屏时间缩短了很多,几乎不可察觉(注意第一次可能还会稍微黑屏一下)。


启动传参


上面我们打开main和second页面没有传参,那么如果想传入一些初始化必要的参数,如何处理?

目前flutter框架并没有封装携带参数的api,也就是说native跳转flutter官方是没有参数。但是我们实际场景又有这样的需求,怎么处理?

官方没有给出相应的api,那么只能从route上想办法。首先改变app中注册route的方式,上面直接使用routes这种map的形式,我们换成onGenerateRoute这种RouteFactory形式,如下:


onGenerateRoute: (RouteSettings settings) {
        if(settings.name.startsWith("second")){
          return MaterialPageRoute(builder: (BuildContext context) {
            return SecondPage(settings.name);
          });
        }
        else {
          return MaterialPageRoute(builder: (BuildContext context) {
            return Scaffold(
              body: Center(
                child: Text("page not found"),
              ),
            );
          });
        }
      },
复制代码


这里的settings.name就是route,因为我们想在route后面添加参数,所以通过开头来判断是那个页面。

注意:示例中直接将route url传给页面,其实应该在这里统一解析出来,以map的形式传给页面。

然后修改Second页面:


class SecondPage extends StatefulWidget{
  String url;
  SecondPage(String url){
    this.url = url;
  }
  @override
  State<StatefulWidget> createState() {
    return _SecondPage();
  }
}
class _SecondPage extends State<SecondPage>{
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("test"),
        ),
        body:Text("test:${widget.url}")
    );
  }
}
复制代码


这里没有解析,直接将url展示出来了,目的是参数传到位即可。

最后在native使用如下代码:


startActivity(FlutterActivity.withNewEngine().initialRoute("second?text=second test").build(this))
复制代码


就可以传递参数了。

但是这样就引出了另外一个问题,因为上面这种启动方式并没有使用engine cache,如果使用engine cache那么route就必须提前定好以便在Appllication中放入cache中。但是我们既然要传参,那么说明route是动态改变的,所以这两个是冲突的,这样在传参的情况下就无法加速启动了么?

因为我们传参本身不是官方api的行为,所以官方的engine cache没有相应的支持。但是这个问题并不是无法解决,比如闲鱼开放的flutter混合框架 —— flutter-boost,就可以很轻松的实现native携参打开flutter页面。不过这里面涉及的东西比较多,后面我单独用一篇文章来解读一下flutter-boost是如何实现传参+快速启动的。



目录
相关文章
|
3月前
|
安全 开发工具 Android开发
几个Flutter常见诊断错误与解决Android toolchain - develop for Android devices X Unable to locate Android SDK
几个Flutter常见诊断错误与解决Android toolchain - develop for Android devices X Unable to locate Android SDK
248 0
|
3月前
|
移动开发 前端开发 JavaScript
探究移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动端混合开发技术在移动应用开发领域日益流行,为开发者提供了更高效的跨平台开发方案。本文将比较三种主流混合开发技术:React Native、Weex和Flutter,从性能、生态系统和开发体验等方面进行评估,以帮助开发者在选择适合自己项目的技术时做出明智的决策。
|
3月前
|
移动开发 前端开发 weex
React Native、Weex、Flutter 混合开发技术的比较与选择
移动应用已经成为人们日常生活中不可或缺的一部分,而混合开发技术也随之崛起并逐渐成为主流。本文将比较 React Native、Weex 和 Flutter 三种混合开发技术,并探讨它们各自的优缺点,以及如何根据项目需求做出选择。
48 1
|
3月前
|
移动开发 前端开发 weex
移动端混合开发技术:React Native、Weex、Flutter 之争
在移动应用开发领域,React Native、Weex 和 Flutter 是备受关注的混合开发技术。本文将对它们进行全面比较与评估,以帮助开发者做出明智的选择。我们将从开发生态、性能、跨平台能力和易用性等方面进行比较,为读者提供全面的参考和指导。
|
3月前
|
移动开发 Dart 前端开发
移动端混合开发技术:React Native、Weex、Flutter的比较与选择
移动应用的开发已经成为现代社会中的重要一环。本文将比较并评估三种主流的移动端混合开发技术:React Native、Weex和Flutter。通过对它们的特点、优势和劣势的分析,帮助开发者在选择适合自己项目的技术方案时做出明智的决策。
|
3月前
|
移动开发 开发框架 前端开发
移动端混合开发技术探析:React Native、Weex、Flutter的比较与选择
随着移动应用开发的高速发展,混合开发技术成为了一种备受关注的选择。本文将对移动端混合开发技术中的React Native、Weex和Flutter进行比较与探讨,分析它们在性能、开发体验、生态系统和跨平台支持等方面的差异,以及如何根据项目需求进行选择。
58 1
|
4月前
|
Dart 开发工具 Android开发
Flutter混合开发:Android中如何启动Flutter
Flutter混合开发:Android中如何启动Flutter 如果你想在你的Android应用中使用Flutter,则需要遵循以下步骤:
|
7月前
|
Dart 开发工具 Android开发
Flutter与iOS原生混合开发
Flutter与iOS原生混合开发
342 2
|
9月前
|
开发框架 Dart 开发工具
使用Flutter开发一套可同时运行在Android和iOS平台的代码
Flutter是一种跨平台移动应用开发框架,它允许开发者使用单一代码库构建高性能、美观且可在多个平台上运行的应用程序。本文将介绍如何使用Flutter开发一套同时适用于Android和iOS平台的代码。
|
10月前
|
Android开发
OPPO手机调试Android Flutter APP时每次都要提示重新安装且不能hot reload
OPPO手机调试Android Flutter APP时每次都要提示重新安装且不能hot reload