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

  • 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,小弟在这里谢过啦

你可能感兴趣的:(Flutter android原生项目引入flutter module)