扩展 TDFModule

大约 3 分钟

扩展 TDFModule

为支持 KuiklyHippy的 Module 生态复用,1.1 版本开始支持使用 TDFModule的方式扩展Module。通过TDFModule扩展的 Module,提供给KuiklyHippy共用,也可以快速将已有的 Hippy Module 迁移到 Kuikly。同时,TDFModule参数传递支持更多的类型。

使用指引

1. Kotlin 侧

Kotlin 侧扩展 Module 方式与旧 Module 扩展基本一致,仅在调用 Native 方法时,将toNative替换为toTDFNaitve,具体使用如下:

(1)继承 Module 类扩展 XXXModule,复写 moduleName 方法,编写 Module API:

class TDFTestModule : Module() {
    override fun moduleName(): String = MODULE_NAME

    companion object {
        const val MODULE_NAME = "TDFTestModule"
    }

    /**
     * 同步调用
     */
    fun syncCallWithReturnValue(
        a1: String?,
        a2: Int?,
        a3: Double?,
        a4: Boolean?,
        a5: Float?,
        a6: List<Any?>?,
        a7: Map<String, Any?>?,
    ) : List<Any?>? {
        val result = toTDFNative(
            false,
            // Native 方法名
            "syncCallWithReturnValue",
            // Native 方法参数列表
            listOf(a1, a2, a3, a4, a5, a6, a7),
            // 异步成功回调,设置为 null
            null,
            // 异步错误回调,设置为 null
            null,
            // 是否同步调用
            true
        )
        // 同步返回结果
        if (result.returnValue is List<*>) {
            return result.returnValue as List<Any?>
        }
        return null
    }

    /**
     * 异步调用
     */
    fun asyncCall(isSuccess: Boolean) {
        toTDFNative(
            false,
            // Native 方法名
            "asyncCall",
            // Native 方法参数列表
            listOf(isSuccess),
            // 异步成功回调
            successCallback = { result ->
                KLog.d("TDFModule", "asyncCall success callback: $result")
            },
            // 异步错误回调
            errorCallback = { result ->
                KLog.d("TDFModule", "asyncCall error callback: $result")
            },
            // 是否同步调用
            false
        )
    }

}

说明:

  • Native 方法参数列表和返回值支持以下类型:

    • Int

    • Long

    • Float

    • Double

    • String

    • Boolean

    • Map<String,Any>

    • List<Any>

Map 和 List 中的 Any 也仅支持以上类型

  • TDFModule 支持同步调用异步调用两种方式:

    • 同步调用:在当前线程支持调用 native 方法,调用结果通过ReturnValue返回,返回值类型见上一点说明;
    • 异步调用:异步调用 native 方法,调用通过 callback 的方式返回,返回值类型见上一点说明;

(2)在 Pager#createExternalModules注册Module

internal abstract class BasePager : Pager() {

    override fun createExternalModules(): Map<String, Module>? {
    		...
        externalModules[TDFTestModule.MODULE_NAME] = TDFTestModule()
        return externalModules
    }

2. Android 侧

(1)继承 TDFBaseModule

(2)添加 @TDFModule注解,name 参数填 module 名

(3)在对应的 native 方法添加 @TDFMethod 注解

@TDFModule(name = "TDFTestModule")
class KRTDFTestModule(context: TDFModuleContext?) : TDFBaseModule(context) {

    @TDFMethod
    fun syncCallWithReturnValue(
        a1: String?,
        a2: Int?,
        a3: Double?,
        a4: Boolean?,
        a5: Float?,
        a6: List<Any?>?,
        a7: Map<String, Any?>?
    ) : List<Any?>{
      	// 同步调用,直接返回结果
        return listOf(1, 2, 3 ,"", listOf<Any>(4, 5, 6), mapOf("a" to 1, "b" to 2))
    }

    @TDFMethod
    fun asyncCall(isSuccess: Boolean, promise: TDFModulePromise) {
        if (isSuccess) {
          	// 异步成功回调
            promise.resolve(mapOf("a" to 1, "b" to 2, "c" to  listOf<Any>(4, 5, 6)))
        } else {
          	// 异步错误回调
            promise.reject(RuntimeException("asyncCall error!!!"))
        }
    }

}

3. iOS 侧

(1)继承 TDFBaseModule

(2)在.m文件中,添加TDF_EXPORT_METHOD(xx) 导出模块

(3)通过TDF_EXPORT_METHOD导出方法

#import "TDFTestModule.h"

@implementation TDFTestModule

TDF_EXPORT_METHOD(syncCall:(NSString *)p1
                  p2:(int)p2
                  p3:(double)p3
                  p4:(BOOL)p4
                  p5:(float)p5
                  p6:(NSArray *)p6
                  p7:(NSDictionary *)p7
                  ) {
    return nil;
}

TDF_EXPORT_METHOD(syncCallWithReturnValue:(NSString *)p1
                  p2:(int)p2
                  p3:(double)p3
                  p4:(BOOL)p4
                  p5:(float)p5
                  p6:(NSArray *)p6
                  p7:(NSDictionary *)p7
                  ) {
    return @[@1, @4, @"1235"];
}
@end

Hippy Module 迁移到 TDFModule

1. Android Hippy Module 迁移

(1)创建 xxxTDFModule 继承 TDFBaseModule

(2)将相关代码迁移到 xxxTDFModule,处理 Hippy 相关依赖,如 HippyEngineContext 等

(3)相关注释、参数类型替换,如下图:

  • @HippyNativeModule 改为 @TDFModule
  • HippyEngineContext 改为 TDFModuleContext
  • @HippyMethod 改为 @TDFMethod
  • HippyMap 改为 Map,HippyArray 改为 List
  • Promise 改为 TDFModulePromise
  • Map/List 与 JsonObject/JsonArray 的转换使用 TDFMapUtils/TDFListUtils 接口

(4)旧 HippyModule 转发

  • 利用 HippyEngineContext 实现 TDFModuleContext 相关接口
  • HippyMap 转成 Map
  • 构造 TDFModulePromise,转发给 Promise

2. iOS Hippy Module 迁移

新建TDFModule(继承自TDFBaseModule)

  1. 拷贝旧module相关代码到新module (若不保留旧module可忽略该步骤)
  2. 修改 HippyExportXXX 为新的 TDFExportXXX
    • HIPPY_EXPORT_MODULE → TDF_EXPORT_MODULE
    • HIPPY_EXPORT_METHOD → TDF_EXPORT_METHOD
  3. 修改旧的callback对象为,新的tdfcallback对象
    • HippyResponseSenderBlock HippyPromiseResolveBlock → TDFModuleSuccessCallback
    • HippyResponseErrorBlock HippyPromiseRejectBlock → TDFModuleErrorCallback
  4. 删除hippy框架的头文件,检查hippy相关的依赖,通过tdfModule的delegate来替换掉,delegate通用能力如下

示例代码

旧HippyModule转发至新TDFModule

核心步骤:旧module仅保留 HippyExport相关接口,并持有新的tdfmodule,将exportMethod转发至新的tdfModule,样例如下:

上次编辑于: