文章目录
-
-
-
- app效果
- [2.修改 Android 项目的 settings.gradle,添加 Flutter module](#2.修改 Android 项目的 settings.gradle,添加 Flutter module)
- [3. 在 Android app 的 build.gradle 中添加依赖](#3. 在 Android app 的 build.gradle 中添加依赖)
- [4. 原生和flutter_module通信BasePlugin](#4. 原生和flutter_module通信BasePlugin)
- [5. io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister 自动注册插件](#5. io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister 自动注册插件)
- [6 手动注册](#6 手动注册)
- [7. 通信关闭flutter页面](#7. 通信关闭flutter页面)
- [8. dartEntrypointArgs传入参数](#8. dartEntrypointArgs传入参数)
- [9. 通信传入参数](#9. 通信传入参数)
-
- [9.1 发送参数](#9.1 发送参数)
- [9.1 接收参数](#9.1 接收参数)
- [10. android代码](#10. android代码)
- [11 源码](#11 源码)
-
-
app效果
#### 1. 创建flutter_module > File->New->New Flutter Project > name为flutter_module > 选择project type为module
2.修改 Android 项目的 settings.gradle,添加 Flutter module
gradle
pluginManagement {
repositories {
google {
content {
includeGroupByRegex("com\\.android.*")
includeGroupByRegex("com\\.google.*")
includeGroupByRegex("androidx.*")
}
}
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.PREFER_SETTINGS)
repositories {
google()
mavenCentral()
maven(url = "https://storage.googleapis.com/download.flutter.io")
}
}
rootProject.name = "hunheandroid"
include(":app")
//主要是这一句
apply(from = "../flutter_module/.android/include_flutter.groovy")
3. 在 Android app 的 build.gradle 中添加依赖
gradle
dependencies {
implementation(project(":flutter"))
}
4. 原生和flutter_module通信BasePlugin
参考文章生成对应的io/flutter/plugins/Messages.g.kt
用pigeon kotlin swift写一个自己的插件拷贝BasePlugin
kotlin
package io.flutter.plugins
import android.app.Activity
import android.util.Log
import androidx.annotation.NonNull
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
/** BasePlugin */
/** BasePlugin */
class BasePlugin : FlutterPlugin, HostMessageApi, ActivityAware {
companion object {
private var flutterMessageApi: FlutterMessageApi? = null
fun getFlutterMessageApi(): FlutterMessageApi? {
return flutterMessageApi
}
}
private var activity: Activity? = null
private var tag = "BasePlugin"
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
Log.e(tag, "onAttachedToEngine-start")
HostMessageApi.setUp(flutterPluginBinding.binaryMessenger, this)
flutterMessageApi = FlutterMessageApi(flutterPluginBinding.binaryMessenger)
Log.e(tag, "onAttachedToEngine-end")
}
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
HostMessageApi.setUp(binding.binaryMessenger, null)
}
override fun flutter2Native(message: String, type: Long): String {
print("flutter2Native=message=start=>$message=type=$type")
return "flutter2Native=message=$message=type=$type"
}
override fun flutter2NativeAsync(
message: String,
type: Long,
callback: (Result<String>) -> Unit
) {
print("flutter2NativeAsync=message=$message=type=$type")
callback(Result.success("flutter2NativeAsync=message=$message=type=$type"))
if (type == 1L) {
closeCurrentActivity()
}
}
private fun closeCurrentActivity() {
activity?.finish()
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
this.activity = binding.activity
}
override fun onDetachedFromActivityForConfigChanges() {
}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
}
override fun onDetachedFromActivity() {
this.activity = null
}
}
5. io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister 自动注册插件
java
public static void registerGeneratedPlugins(@NonNull FlutterEngine flutterEngine) {
try {
Class<?> generatedPluginRegistrant =
Class.forName("io.flutter.plugins.GeneratedPluginRegistrant");
Method registrationMethod =
generatedPluginRegistrant.getDeclaredMethod("registerWith", FlutterEngine.class);
registrationMethod.invoke(null, flutterEngine);
} catch (Exception e) {
Log.e(
TAG,
"Tried to automatically register plugins with FlutterEngine ("
+ flutterEngine
+ ") but could not find or invoke the GeneratedPluginRegistrant.");
Log.e(TAG, "Received exception while registering", e);
}
}
java
package io.flutter.plugins;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterEngine;
/**
* Generated file. Do not edit.
* This file is generated by the Flutter tool based on the
* plugins that support the Android platform.
*/
@Keep
public final class GeneratedPluginRegistrant {
private static final String TAG = "GeneratedPluginRegistrant";
public static void registerWith(@NonNull FlutterEngine flutterEngine) {
try {
Log.e(TAG, "registerWith-start");
flutterEngine.getPlugins().add(new BasePlugin());
Log.e(TAG, "registerWith-end");
} catch (Exception e) {
Log.e(TAG, "Error registering plugin base_plugin, com.app.base_plugin.BasePlugin", e);
}
}
}
6 手动注册
flutterEngine.getPlugins().add(new BasePlugin());
7. 通信关闭flutter页面
使用flutter和原生通信,在收到消息以后,关闭当前页面
BasePlugin实现ActivityAware,获取到activity
在收到flutter传入进来的消息的时候关闭activity
8. dartEntrypointArgs传入参数
kotlin
//跳转带入参数
val initialRoute = listOf(
"aaa",
"bbbb"
)
startActivity(
withNewEngine()
.dartEntrypointArgs(initialRoute)
.build(this)
)
dart
//args就是传入的参数
void main(List<String> args){
print("args=$args");
runApp(const MyApp());
}
9. 通信传入参数
9.1 发送参数
kotlin
val initialRoute = listOf(
"/page2",
"bbbb"
)
BasePlugin.getFlutterMessageApi()?.native2Flutter(initialRoute.joinToString("#"), 1){
Log.e(tag, "flutter2NativeAsync: $it")
FlutterLibrary.startFlutterPage(this)
}
9.1 接收参数
dart
class RouterPage extends StatefulWidget {
const RouterPage({super.key});
@override
State<RouterPage> createState() => _RouterPageState();
}
class _RouterPageState extends State<RouterPage> implements FlutterMessageApi {
late String args;
@override
void initState() {
super.initState();
FlutterMessageApi.setUp(this);
}
@override
String native2Flutter(String message, int type) {
print("native2Flutter=$message $type");
setState(() {
args = message;
});
return "我是原生调用flutter方法返回的值=》native2Flutter";
}
@override
Future<String> native2FlutterAsync(String message, int type) {
args = message;
print("native2Flutter=$message $type");
return Future.value("我是原生调用flutter方法返回的值=》native2FlutterAsync");
}
@override
Widget build(BuildContext context) {
// final value = widget.args.isNotEmpty ? widget.args[0] : "/";
if (args.isEmpty||!args.contains("#")) {
return MyHomePage(title: "首页");
}
final value = args.split("#").first;
switch (value) {
case '/page2':
return SecondPage();
}
print("_RouterPageState=build");
return MyHomePage(title: "首页");
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
void initState() {
super.initState();
}
@override
Widget build(BuildContext context) {
print("_MyHomePageState=build");
return Scaffold(
appBar: AppBar(title: Text(widget.title), leading: BackButton()),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
TextButton(
onPressed: () {
BasePlugin.flutter2NativeAsync("flutter2NativeAsync", 1).then((
value,
) {
print("flutter2NativeAsync=$value");
});
},
child: Text('flutter2NativeAsync'),
),
TextButton(
onPressed: () {
Navigator.of(context).pushNamed("/page2");
},
child: Text('flutter2NativeAsync'),
),
const Text('You have pushed the button this many times:'),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
}
class SecondPage extends StatelessWidget {
const SecondPage({super.key});
@override
Widget build(BuildContext context) {
print("SecondPage=build");
return Scaffold(
appBar: AppBar(title: Text("SecondPage")),
body: Center(
child: TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: Text('关闭'),
),
),
);
}
}
10. android代码
kotlin
package com.example.hunheandroid
import android.app.Application
import android.content.Context
import android.content.Intent
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.FlutterEngineCache
import io.flutter.embedding.engine.FlutterEngineGroup
import io.flutter.embedding.engine.dart.DartExecutor
import io.flutter.plugins.BasePlugin
const val ENGINE_ID = "my_engine_id"
object FlutterLibrary {
fun init(application: Application) {
FlutterEngineManager.getInstance().init(application)
}
fun startFlutterPage(context: Context) {
val intent = FlutterActivity
.withCachedEngine(ENGINE_ID)
.build(context).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
context.startActivity(intent)
}
}
// FlutterEngineManager.kt
class FlutterEngineManager private constructor() {
private lateinit var engineGroup: FlutterEngineGroup
private var engine: FlutterEngine? = null
companion object {
private var instance: FlutterEngineManager? = null
fun getInstance(): FlutterEngineManager {
return instance ?: synchronized(this) {
instance ?: FlutterEngineManager().also { instance = it }
}
}
}
fun init(application: Application) {
engineGroup = FlutterEngineGroup(application)
engine = engineGroup.createAndRunEngine(
application,
DartExecutor.DartEntrypoint.createDefault()
)
FlutterEngineCache.getInstance().put(ENGINE_ID, engine)
engine!!.plugins.add(BasePlugin())
}
fun getEngine(): FlutterEngine? {
return engine
}
fun destroyEngine() {
engine?.destroy()
engine = null
}
}
class GoFlutterActivity : FlutterActivity(), HostMessageApi {
private val tag = "GoFlutterActivity"
private lateinit var binding: ActivityGoFlutterBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityGoFlutterBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.goFlutter.setOnClickListener {
//跳转到flutter
val initialRoute = listOf( // Map 形式的参数
"/",
"aaaa"
)
BasePlugin.getFlutterMessageApi()?.native2Flutter(initialRoute.joinToString("#"), 1) {
Log.e(tag, "flutter2NativeAsync: $it")
FlutterLibrary.startFlutterPage(this)
}
}
binding.goFlutter2.setOnClickListener {
//跳转到flutter
val initialRoute = listOf( // Map 形式的参数
"/page2",
"bbbb"
)
BasePlugin.getFlutterMessageApi()?.native2Flutter(initialRoute.joinToString("#"), 1) {
Log.e(tag, "flutter2NativeAsync: $it")
FlutterLibrary.startFlutterPage(this)
}
}
}
override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
Log.e(tag, "configureFlutterEngine")
// GeneratedPluginRegistrant.registerWith(flutterEngine)
}
override fun flutter2Native(message: String, type: Long): String {
Log.e(tag, "$message$type")
return "我是flutter调用原生方法的返回值=》flutter2Native"
}
override fun flutter2NativeAsync(
message: String,
type: Long,
callback: (Result<String>) -> Unit
) {
Log.e(tag, "$message$type")
callback(Result.success("我是flutter调用原生方法的返回值=》flutter2NativeAsync"))
}
}