Flutter android原生项目引入flutter module

前言:

各位同学的大家好,有段时间没有给大家更新文章了,最近在学习flutter和安卓混合开发的知识点。所以就像总结一下,然后后分享给大家。 这一期文章的讲的知识一定要有用到Android studio 所以用vscode开发同学要稍微改下IDE (但是这不是重点)
那么废话不多说我们正式开始。

准备工作

需要安装flutter的开发环境:大家可以去看看之前的教程:
1 win系统flutter开发环境安装教程: https://www.jianshu.com/p/152447bc8718
2 mac系统flutter开发环境安装教程:https://www.jianshu.com/p/bad2c35b41e3
效果图:

image.png

image.png

具体实现

一 创建flutter_module 工程

  • 1用Android studio 创建或者命令都可以

image.png

image.png
  • 2 命令创建

flutter create -t module flutter_module

这里要注意安卓原生项目需要跟flutter_module在同一个目录层级

第二步创建安卓原生工程

image.png


这个就比较简单了 我就不多说了按照截图一路下一步即可

三在Android 项目中进入flutter_module

  • 1 在原生Android项目里面的 app目录下面的 build.gradle里面添加如下代码
compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
image.png

我们知道这是使用Java 8所需要的配置,在这里的作用是为了解决版本兼容问题,如果不配置的话运行项目可能会报错:Invoke-customs are only supported starting with Android O (--min-api 26)。

  • 2然后在项目根目录下的setting.gradle文件中配置:

// 加入下面配置
setBinding(new Binding([gradle: this]))
evaluate(new File(
        settingsDir.parentFile,
        'flutter_module/.android/include_flutter.groovy'
))
image.png

flutter_module 这个记得修改成自己的flutter module 的名称 之后sync 一下·项目 即可导入成功

这里要注意我们在sync 的时候我们要同时打开flutter module 项目和原生安卓项目否则会失败


image.png

sync之后我们发现原生工程工程的目录结构里面多出一flutter名字的library module 的库工程 我们需要在app目录下的build.gradle 里面添加该module的依赖

  implementation project(':flutter')
image.png

这样我们就讲flutter_module工程引入到我们的Android项目项目里面来 当然flutter_module其实也是可以单独运行的

android 原生页面打开flutter页面

  • 一添加普通的Flutter屏幕

Flutter提供FlutterActivity了在Android应用程序中显示Flutter体验的功能。像任何其他一样Activity, FlutterActivity必须在您的帐户中注册 AndroidManifest.xml。将以下XML添加到 标签AndroidManifestxml下的文件中application:

 <activity
android:name="io.flutter.embedding.android.FlutterActivity"
 android:theme="@style/Theme.Nativedemo"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
 android:hardwareAccelerated="true"
  android:windowSoftInputMode="adjustResize"
    />
  • 二 启动activity

  • 1使用FlutterActivity.createDefaultIntent
 startActivity(FlutterActivity.createDefaultIntent(MainActivity.this));

这个示例假设您的Dart入口点称为main(),初始Flutter路线为“ /”。无法使用更改Dart入口点Intent,但可以使用更改初始路线Intent。这个方法打开的是flutter默认入口不能自定义你想要打开的flutter的页面

  • 2 使用 FlutterActivity.withNewEngine().initialRoute 这种方式
startActivity(FlutterActivity.withNewEngine().initialRoute("route_page").build(MainActivity.this));

这个就可以通过在 initialRoute 里面传入你flutter module 项目里面配置的命名路由地址 从而选择打开你想要打开的flutter页面

  • 3 启动flutteractivity并且传值


    image.png

    image.png

    我们还是在通过 FlutterActivity.withNewEngine().initialRoute 在initialRoute 里面传传值

  startActivity(FlutterActivity.withNewEngine().initialRoute("{name:'xq9527'}").build(MainActivity.this));

flutter module 里面如何接收数据

import 'package:flutter/material.dart';
import 'dart:ui';
import 'my_home_page.dart';
import 'default_page.dart';

void main() => runApp(
     MyApp(initParams:window.defaultRouteName));
class MyApp extends StatelessWidget {
  String initParams = '';
  MyApp({this.initParams});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
        // routes: {
        //   "/": (context) => DefaultPage(title: '路由默认页面'),
        //   'route_page':(context) => MyHomePage(title: '路由页面Page1'),
        // },

     // home: "/",

      home: MyHomePage(title: this.initParams,),
    );
  }
}

在flutter module 我们需要在入口main方法中实例化的myapp 入口的时候 传入window.defaultRouteName 我们的默认路由的参数 然后在我们的flutter中去使用原生传过来的数据


使用FlutterEngine
package com.example.nativedemo;

import android.app.Application;
import io.flutter.embedding.engine.FlutterEngine;
import io.flutter.embedding.engine.FlutterEngineCache;
import io.flutter.embedding.engine.dart.DartExecutor;


/***
 *
 *创建人xuqing
 * 创建时间:2021/4/20
 * 类说明:启动入口
 */

public class MyApplication extends Application {
    public static final String ENGINEID = "my_engine_id";
    @Override
    public void onCreate() {
        super.onCreate();
        initFlutterEngine();
    }
    private void initFlutterEngine(){
        // Instantiate a FlutterEngine.
        FlutterEngine flutterEngine = new FlutterEngine(this);
        flutterEngine.getNavigationChannel().setInitialRoute("route_page");// 配置默认启动路由
        // Start executing Dart code to pre-warm the FlutterEngine.
        flutterEngine.getDartExecutor().executeDartEntrypoint(
                DartExecutor.DartEntrypoint.createDefault()
        );
        // Cache the FlutterEngine to be used by FlutterActivity.
        FlutterEngineCache
                .getInstance()
                .put(ENGINEID, flutterEngine);
    }
}

使用方式

   FlutterActivity.withCachedEngine(MyApplication.ENGINEI).build(MainActivity.this);

使用FlutterFragment

  • 默认启动方式
 FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
        FlutterFragment flutterFragment=null;
        //默认启动方式
        flutterFragment = FlutterFragment.createDefault();
        fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
        fragmentTransaction.commit();
  • 指定路由页面

FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
        FlutterFragment flutterFragment== FlutterFragment.withNewEngine()
                .initialRoute("route_page")
                .build();
        fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
        fragmentTransaction.commit();
  • 使用FlutterEngine
  FragmentTransaction fragmentTransaction=getSupportFragmentManager().beginTransaction();
        FlutterFragment flutterFragment== FlutterFragment.withCachedEngine(MyApplication.ENGINEID)
                .renderMode(RenderMode.surface)
                .build();
        fragmentTransaction.add(R.id.main_framelayout, flutterFragment);
        fragmentTransaction.commit();

还有可以使用flutterview 我这边就不展开讲了有兴趣的同学可以查看官方文档
Add Flutter to existing apps

最后总结

Android 原生引入flutter module 实现起来相对比较简单 官方文档也比较详细,但是也有坑,我在文章中也提到了 这一期文章主要介绍了Android 引入flutter module 的基础知识点 如果有纰漏请指正谢谢。最后希望我的文章能帮助到各位解决问题 ,以后我还会贡献更多有用的代码分享给大家。各位同学如果觉得文章还不错 ,麻烦给关注和star,小弟在这里谢过啦

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351

推荐阅读更多精彩内容