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

相关推荐
还鮟2 小时前
CTF Web的数组巧用
android
小蜜蜂嗡嗡3 小时前
Android Studio flutter项目运行、打包时间太长
android·flutter·android studio
aqi003 小时前
FFmpeg开发笔记(七十一)使用国产的QPlayer2实现双播放器观看视频
android·ffmpeg·音视频·流媒体
zhangphil5 小时前
Android理解onTrimMemory中ComponentCallbacks2的内存警戒水位线值
android
你过来啊你5 小时前
Android View的绘制原理详解
android
瓜子三百克7 小时前
十、高级概念
flutter
移动开发者1号8 小时前
使用 Android App Bundle 极致压缩应用体积
android·kotlin
移动开发者1号8 小时前
构建高可用线上性能监控体系:从原理到实战
android·kotlin
ii_best13 小时前
按键精灵支持安卓14、15系统,兼容64位环境开发辅助工具
android
美狐美颜sdk13 小时前
跨平台直播美颜SDK集成实录:Android/iOS如何适配贴纸功能
android·人工智能·ios·架构·音视频·美颜sdk·第三方美颜sdk