Flutter android原生项目引入flutter mod
前言:
各位同学的大家好,有段时间没有给大家更新文章了,最近在学习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
具体实现
一 创建flutter_module 工程
-
1用Android studio 创建或者命令都可以
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,小弟在这里谢过啦