android,flutter 混合开发,通信,传参

文章目录

        • 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"))

    }


}
11 源码

gitee

相关推荐
风浅月明9 小时前
[Android]如何判断当前APP是Debug还是Release环境?
android
freflying11199 小时前
使用jenkins构建Android+Flutter项目依赖自动升级带来兼容性问题及Jenkins构建速度慢问题解决
android·flutter·jenkins
私人珍藏库11 小时前
[Android] APK提取器(1.3.7)版本
android
m0_7482326411 小时前
mysql的主从配置
android·mysql·adb
机器瓦力11 小时前
Flutter应用开发:对象存储管理图片
flutter
秋长愁11 小时前
Android监听应用前台的实现方案解析
android
胖虎112 小时前
2025 新版Android Studio创建Java语言项目
android·java·android studio·创建java项目
JabamiLight13 小时前
Lineageos 22.1(Android 15)Launcer简单调整初始化配置
android·android 15·lineageos 22.1·launcer
敲代码的鱼哇15 小时前
设备唯一ID获取,支持安卓/iOS/鸿蒙Next(uni-device-id)UTS插件
android·ios·uniapp·harmonyos
太空漫步1116 小时前
android滑动看新闻
android