Android 注解自动生成与 Flutter 通信的代码

Overview

Android-Flutter-Annotation

用于 Android 端项目,通过使用注解自动生成与 Flutter 通信的代码。

可生成的三种通信渠道有:

  • MethodChannel
  • EventChannel
  • BasicMessageChannel

集成

在项目的 build.gradle 添加 jitpack 仓库的依赖

allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

在 module 的 build.gradle 中添加

apply plugin: 'kotlin-kapt'

dependencies {
    implementation "com.github.joyyued.android-flutter-annotation:annotation:1.0.0"
    kapt "com.github.joyyued.android-flutter-annotation:compiler:1.0.0"
}

使用

Flutter 引擎

用于标记 Flutter 引擎的 id,会生成创建 Flutter 引擎 id 的代。并注解生成的 channel 会默认使用该 engineId。

@FlutterEngine(engineId = "引擎 id")
class MyFlutterEngine {}

使用此注解之后,可以进行以下操作

// 引擎初始化
Flutter.init(context)

// 引擎释放
Flutter.release()

// 获取默认 flutter 引擎
Flutter.Engine.DEFAULT_ENGINE

// engineId 可以不传,默认则为注解的 engineId
Flutter.Engine.getEngine("引擎 id")

MethodChannel

由 MethodChannel 特征决定了,可以通过该渠道在 Native 接收来自 Flutter 的信息,也可以在 Native 发送信息给 Flutter,使用中请注意 接收发送 的类型。

@FlutterMethodChannel

用于生成 Android 端中,与 Flutter 通信的 MethodChannel 代码

接收者 [Flutter -> Native]

@FlutterMethodChannel(
    type = ChannelType.RECEIVER,
    channelName = ChannelConfig.METHOD_CHANNEL
)
class NezaMethodChannel {

    @Receive
    fun sayHelloToNative() {
        sayHello()
    }

    fun sayHello() {
        Log.e("NezaMethodChannel", "[Flutter -> Native] sayHelloToNative")
    }

}

在需要接收信息的方法加上 @Receive 注解,则当 Flutter 端调用渠道名称为 ChannelConfig.METHOD_CHANNEL 的渠道,并且方法为 sayHelloToNative 时,则框架则会调用至该方法。

发送者 [Native -> Flutter]

@FlutterMethodChannel(
    type = ChannelType.SENDER,
    channelName = ChannelConfig.METHOD_CHANNEL
)
interface NezaMethodChannel {
    fun sayHelloToFlutter()
}

使用此注解后,可以通过以下代码进行发送信息给 Flutter,发送的方法名为所定义的方法名称(例子中则为 sayHelloToFlutter

Flutter.channels?.nezaMethodChannel?.sayHelloToFlutter()

// 如果需要返回值,则只需要将其包裹至协程,进行同步即可
CoroutineScope(Dispatchers.Main).launch {
    val result = Flutter.channels
        ?.nezaMethodChannel
        ?.sayHelloToFlutter()
        ?.await()
        // do something
}

协程返回的内容结构如下,可以根据 resultType 进行区分结果类型,再获取相应的数据。

data class MethodChannelResult(
    val resultType: MethodChannelResultType,
    val successResult: SuccessResult? = null,
    val errorResult: ErrorResult? = null,
)

@ParseData

用于在接收者中,框架会以方法的参数名作为 key 值获取从 Flutter 传过来的 value,如下代码所示

@FlutterMethodChannel(
    type = ChannelType.RECEIVER,
    channelName = Config.METHOD_CHANNEL
)
class NezaMethodChannel {
    @ParseData
    fun sayHelloToNativeWithParam(name: String?, age: Int?) {
        // do something
    }
}
  • 使用 @ParseData 注解的参数类型都需要为可空,即需要为 String? ,不能为 String
  • 不使用 @ParseData 注解,则参数个数必须为 0 或 1 个,如果 1 个参数,该参数类型必须为 Any

@Receive

用于接收者,被标记的方法默认会接收 Flutter 传递过来的同渠道同方法名的信息,可以通过设置属性 name , 更改回调方法名

  • 可以与 @ParseData 同时使用,此时框架会尝试着进行解析参数,但参数类型必须为可空,即需要为 String?,不能为 String
  • 如果只是单独使用,则参数个数必须为 0 或 1 个,如果 1 个参数,该参数类型必须为 Any

@Send

用于发送者,默认发送者会使用接口定义的方法名作为调用 Flutter 端的方法名称,通过设置该注解的 name 属性,可以更改这一默认行为,使用 name 的值进行调用

@Callback

用于标记回调的参数,在 Method Channel 中,必须为 io.flutter.plugin.common.MethodChannel.Result 类型的属性。

框架会在每次接收到 Flutter 传递的信息时,将回调设置到该参数,方法中可以进行逻辑处理后传递返回值给 Flutter 端

代码使用如下

@FlutterMethodChannel(
    type = ChannelType.RECEIVER,
    channelName = Config.METHOD_CHANNEL
)
class NezaMethodChannel {

    @Receive
    fun sayHelloToNativeWithRaw(
        map: Any,
        @Callback result: MethodChannel.Result
    ) {
        //  your logic

        // success
        result.success("")

        // error
        result.error("code", "message", "detail")

        // notImplemented
        result.notImplemented()
    }

}

EventChannel

由于 EventChannel 特征决定了,只能单向从 Native 发送信息给 Flutter,所以相较于 MethodChannel 渠道,只有发送者。

@FlutterEventChannel

用于标记需要生成 Flutter Event Method 通信的代码

@FlutterEventChannel(channelName = ChannelConfig.EVENT_CHANNEL)
interface NezaEventChannel {
    @Param
    fun sendImageInfo(byteArray: ByteArray)
}

可以通过以下代码进行调用

Flutter.channels?.nezaEventChannel?.sendImageInfo(byteArray)

BasicMessageChannel

由于 BasicMessageChannel 特征决定了,可以通过该渠道在 Native 接收来自 Flutter 的信息,也可以在 Native 发送信息给 Flutter,使用中请注意 接收发送 的类型。

同时还需要一个 解析器(注解中的 codeccClass)进行对数据的解析,谷歌官方提供了四种解析器:

  1. io.flutter.plugin.common.BinaryCodec
  2. io.flutter.plugin.common.JSONMessageCodec
  3. io.flutter.plugin.common.StandardMessageCodec
  4. io.flutter.plugin.common.StringCodec

当然你也可以进行自定义适合自己的解析器,但值得注意的是,你必须像官方代码一样提供一个 INSTANCE 的静态公开的实例属性。

@FlutterBasicChannel

用于生成 Android 端中,与 Flutter 通信的 Basic Message Channel 代码

接收者 [Flutter -> Native]

@FlutterBasicChannel(
    codecClass = StringCodec::class,
    channelName = ChannelConfig.STANDER_BASIC_CHANNEL,
    type = ChannelType.RECEIVER
)
object NezaBasicChannel {
    @Receive
    fun receiverJsonFromFlutter(json: String) {
        Log.e("NezaBasicChannel", "[Flutter -> Native]$json")
    }
}

当 Flutter 端调用渠道名称为 ChannelConfig.STANDER_BASIC_CHANNEL 的渠道时,框架则会调用标记了 @Receive 注解的方法。

发送者 [Native -> Flutter]

@FlutterBasicChannel(
    codecClass = StringCodec::class,
    channelName = ChannelConfig.EVENT_CHANNEL,
    type = ChannelType.SENDER
)
interface NezaBasicChannel {
    @Param
    fun sendJsonToFlutter(json: String)
}

可以通过以下代码进行发送信息给 Flutter

Flutter.channels?.nezaStringBasicChannel?.sendJsonToFlutter("{\"name\":\"江澎涌\"}")

// 如果需要返回值,则只需要将其包裹至协程,进行同步即可
CoroutineScope(Dispatchers.Main).launch {
    Flutter.channels
        ?.nezaStringBasicChannel
        ?.sendJsonToFlutter("{\"name\":\"江澎涌\", \"age\":28}")
        ?.await()

    // do something
}

@Receive

用于在接收者中,标记需要处理接收到信息的方法,切记标记的方法参数类型要和 codec 的泛型一致

  • 如果存在多个 @Receive ,则只有最后一个方法会被调用
  • 如果没有 @Receive,则没有回调触发

@Callback

在接收者中,用于标记回调 Flutter 的参数,属性的类型必须为 io.flutter.plugin.common.BasicMessageChannel.Reply<T>

框架会在每次接收到 Flutter 传递的信息时,将回调设置到该参数,方法中可以进行逻辑处理后传递返回值给 Flutter 端

代码使用如下

@FlutterBasicChannel(
    codecClass = StringCodec::class,
    channelName = Config.STRING_BASIC_CHANNEL,
    type = ChannelType.RECEIVER
)
class NezaStringBasicChannel {

    @Receive
    fun receiverJsonFromFlutter(
        json: String?,
        @Callback reply: BasicMessageChannel.Reply<String>
    ) {
        Log.e("NezaBasicChannel", "[Flutter -> Native] $json")
        reply.reply("Reply something......")
    }

}

添加参数

三种 channel 发送者的方法都可以携带参数,可以使用 @Param@ParamMap 对方法标注

  • @Param: 代表只使用第一个参数的 值 和 类型作为传递值和传递类型。
  • @ParamMap: 代表会将参数组织为一个 HashMap 进行传递,参数名称为 key,参数值为 value。

值得注意:

  1. 同时使用两个注解,框架会抛出错误
  2. 不使用注解,则框架会通过参数个数进行默认行为:1 个参数则以标注了 @Param 处理,其余情况以标注了 @ParamMap 处理
  3. 当多参数的方法,使用了 @Param 注解,框架不会报错,内部逻辑只会使用第一个参数作为传递参数,传递类型也是第一个参数类型,其余的参数将形同虚设。

LICENSE

MIT

You might also like...
A flutter plugin to add Mapbox Navigation into flutter app

mapbox A new Flutter project. Getting Started This project is a starting point for a Flutter plug-in package, a specialized package that includes plat

Open as default - A flutter plugin that allows setting up your flutter app to open files as default
Open as default - A flutter plugin that allows setting up your flutter app to open files as default

open_as_default A flutter plugin that allows setting up your flutter app to open

Audio Tagger library for Flutter (Android only)

audio_tagger A Flutter (Android only) plugin for editing and extracting information from your music, at the moment it only works on AAC and OGG (last

A flutter plugin allows you to create native android floating window.
A flutter plugin allows you to create native android floating window.

A flutter plugin allows you to create native android floating window.

Android Alarm Clock Plugin for Flutter.
Android Alarm Clock Plugin for Flutter.

Android Alarm Clock Plugin for Flutter This plugin allows Flutter apps to operate with the default clock application when the platform is Android. Pro

Google one tap sign in - Flutter Google One Tap Sign In (Android)
Google one tap sign in - Flutter Google One Tap Sign In (Android)

Google One Tap Sign In Google One Tap Sign In (Android) A Flutter Plugin for Google One Tap Sign In Getting Started To access Google Sign-In, you'll n

1aingenieriaygas native base android - Project base for the migration of the Flutter App of 1A Ingenieria y Gas
1aingenieriaygas native base android - Project base for the migration of the Flutter App of 1A Ingenieria y Gas

1A Ingenieria y Gas App Versión Wordpress Backend Este proyecto se encuentra sol

A Flutter implementation of Salesforce Marketing Cloud for iOS and Android

sfmc_flutter A Flutter implementation of Salesforce Marketing Cloud for iOS and Android. Features Setup Marketing Cloud (iOS and Android) Support for

A plugin for Android Studio that speeds up your day-to-day flutter development.

Flutter-Toolkit 中文文档 A plugin for Android Studio that speeds up your day-to-day flutter development. Flutter ToolKit(Flutter Build Runner Helper), to

A Simple Todo app design in Flutter to keep track of your task on daily basis. Its build on BLoC Pattern. You can add a project, labels, and due-date to your task also you can sort your task on the basis of project, label, and dates
A Simple Todo app design in Flutter to keep track of your task on daily basis. Its build on BLoC Pattern. You can add a project, labels, and due-date to your task also you can sort your task on the basis of project, label, and dates

WhatTodo Life can feel overwhelming. But it doesn’t have to. A Simple To-do app design in flutter to keep track of your task on daily basis. You can a

A clone of the TikTok App using Flutter.
A clone of the TikTok App using Flutter.

Tik Tok App clone TikTok is an iOS and Android media app for creating and sharing short videos. The app was launched in 2017 by ByteDance, for markets

The easy way to use biometric authentication in your Flutter app. Supports Fingerprint, FaceID and Iris.
The easy way to use biometric authentication in your Flutter app. Supports Fingerprint, FaceID and Iris.

BiometricX The easy way to use biometric authentication in your Flutter app. Supports Fingerprint, FaceID and Iris. Demo APK. Starting $ flutter pub a

A flutter plugin through which you can get audios, videos, or images from the local storage.

Getter Made flutter easier. Description A flutter plugin through which you can get audios, videos or images from the local storage. Dependencies Befor

A simple screen that is shown when your app gets crashed instead of the normal crash dialog. It's very similar to the one in Flutter.
A simple screen that is shown when your app gets crashed instead of the normal crash dialog. It's very similar to the one in Flutter.

Red Screen Of Death What A simple screen that is shown when your app gets crashed instead of the normal crash dialog. It's very similar to the one in

Zendesk-Messaging for Flutter developer
Zendesk-Messaging for Flutter developer

Zendesk Messaging Messaging is a "user-based" chat Live Chat is a "session-based" chat Better UI (Native) Chat history Answer Bot Setup 1. Enable agen

Flutter plugin for Juspay Payment SDK

juspay_flutter A flutter plugin for juspay payment SDK. Flutter Setup Add plugin dependency in pubspec.yaml dependencies: juspay_flutter: git:

use kmm to write a flutter plugin
use kmm to write a flutter plugin

use KMM to write a flutter plugin The reference plugin_codelab example plugin that accompanies the How to write a Flutter plugin codelab. I changed pl

A Flutter plugin that retrieves images and videos from mobile native gallery

Photo Gallery A Flutter plugin that retrieves images and videos from mobile native gallery. Installation First, add photo_gallery as a dependency in y

Releases(1.0.0-beta.3)
Owner
JOYY UED
欢聚集团用户体验设计中心
JOYY UED
Android Parcelable models made easy

AutoParcel AutoParcel is an AutoValue extension that enables Parcelable values generation. Just add implements Parcelable to your @AutoValue annotated

Francesco Sardo 1.4k Dec 23, 2022
A tool to generate Android ContentProviders.

Android ContentProvider Generator (acpg) A tool to generate Android ContentProviders. It takes a set of entity (a.k.a "table") definitions as the inpu

Benoit Lubek 623 Dec 13, 2022
A custom view styling library for Android that generates the obtainStyledAttributes() and TypedArray boilerplate code for you.

DEPRECATED This project is no longer maintained. Consider using https://github.com/airbnb/paris Barber Barber is your personal custom view stylist. Si

Zac Sweers 716 Dec 30, 2022
A easy way to use android sharepreference

Favor A easy way of using Android SharedPreferences. How to use this library Using Gradle compile 'com.cocosw:favor:0.2.0@aar' Using Maven <depend

Kai Liao 467 Nov 10, 2022
A code generator to create Android ContentProvider

DatabaseCodeGenerator This project is a code generator written in Java used to generate Android code. Given a database schema JSON definition file, it

Foxykeep 297 Nov 25, 2022
Pure Java code generation tool for generating a fully functional ContentProvider for Android.

RoboCoP RoboCoP is a Java library that can generate a fully-functional ContentProvider from a simple JSON schema file. Get the latest version from our

Rain 246 Dec 29, 2022
Codegeneration tool for isomorphic server and mobile Go apps with gRPC & Protobuf. Share code between your backend, Android & iOS app! :sun_with_face:

Anakin Codegeneration tool for isomorphic server and mobile Go apps with gRPC & Protobuf. Share code between your backend, Android & iOS app! Descript

Kirill Biakov 17 Jun 25, 2020
A small tool to help you generate android projects that have a base code.

Volt Project A small tool to help you generate android projects that have a base code. Usage Change project in base directory. python volt-gen.py <pac

Victor Varenik 3 Feb 2, 2022
Esp touch flutter plugin - Client-side (mobile) Android Flutter implementation for ESP-Touch protocol

esp_touch_flutter_plugin Client-side (mobile) Android Flutter implementation for

huangyanxiong 0 Jan 21, 2022