Files
Hippy/docs/android/custom-module.md
2022-08-17 17:54:24 +08:00

4.8 KiB
Executable File
Raw Permalink Blame History

自定义终端模块

很多时候 JS 需要访问对应终端的一些能力模块,比如数据库、下载、网络请求等,这时候就需要使用 Module 来暴露接口给JS使用。Hippy SDK 中默认实现了部分 Module,但这极有可能无法满足你的需求,这就需要你对 Module 进行扩展封装。


Module扩展

我们将以 TestModule 为例,从头扩展一个 Module,这个 Module 将展示前端如何调用终端能力,并且把结果返回给前端。

终端扩展Module包括四步:

  1. 创建 HippyNativeModuleBase 的子类。
  2. 添加 HippyNativeModule 注解。
  3. 实现导出给 JS 的方法。
  4. 注册 Module。

1. 创建HippyNativeModuleBase的子类

首先我们需要创建TestModule类,并且继承HippyNativeModuleBase。

package com.tencent.mtt.hippy.example.modules;

import com.tencent.mtt.hippy.HippyEngineContext;
import com.tencent.mtt.hippy.modules.nativemodules.HippyNativeModuleBase;

public class TestModule extends HippyNativeModuleBase
{

    public LogModule(HippyEngineContext context)
    {
        super(context);
    }
}

2. 添加HippyNativeModule注解

HippyNativeModuleBase 要求增加注解 @HippyNativeModule 。

HippyNativeModule有两个注解参数:

  • name:能力名称,js调用时需要通过此访问该能力。
  • thread:能力运行的线程。包括 HippyNativeModule.Thread.DOM(Dom线程)、HippyNativeModule.Thread.MAIN(主线程)、HippyNativeModule.Thread.BRIDGE(Bridge线程、默认值)。
@HippyNativeModule(name = "TestModule", thread = HippyNativeModule.Thread.BRIDGE)
public class TestModule extends HippyNativeModuleBase
{
    ...
}

3. 实现导出给JS的方法

导出给 JS 使用的方法,必须使用注解 @HippyMethod ,方法必须为 public 类型,返回类型必须为 void。

支持的方法参数类型包括:

  • Java基本数据类型。
  • HippyArray:类似于ArrayList,线程非安全。
  • HippyMap:类似于HashMap,线程非安全。
  • Promise:回调JS的触发器,通过 resolve 方法返回成功信息给JS。通过 reject 方法返回失败实现给JS。
@HippyMethod(name="log")
public void log(String msg)
{
    Log.d("TestModule", msg);
}

@HippyMethod(name="helloNative")
public void helloNative(HippyMap hippyMap)
{
    String hello = hippyMap.getString("hello");
    Log.d("TestModule", hello);
}

@HippyMethod(name = "helloNativeWithPromise")
public void helloNativeWithPromise(HippyMap hippyMap, Promise promise)
{
    // 这里回来的参数可以为java的基础类型,和hippymap与hippyarry, 但是前端调用的时候必须对应上
    String hello = hippyMap.getString("hello");
    Log.d("TestModule", hello);
    if (true)
    {
        // TODO 如果模块这里处理成功回调resolve
        HippyMap hippyMap1 = new HippyMap();
        hippyMap1.pushInt("code", 1);
        hippyMap1.pushString("result", "hello i am from native");
        promise.resolve(hippyMap1);
    }
    else
    {
        // 失败就回调reject
        HippyMap hippyMap1 = new HippyMap();
        hippyMap1.pushInt("code", -1);
        promise.reject(hippyMap1);
    }
}

4. 注册Module

然后需要注册这个Module。需要在 HippyPackage 的 getNativeModules 方法中添加这个 Module,这样它才能在JS中被访问到。

import com.tencent.mtt.hippy.HippyEngineContext;
import com.tencent.mtt.hippy.HippyPackage;
import com.tencent.mtt.hippy.common.Provider;
import com.tencent.mtt.hippy.example.module.TestModule;

import com.tencent.mtt.hippy.modules.javascriptmodules.HippyJavaScriptModule;
import com.tencent.mtt.hippy.modules.nativemodules.HippyNativeModuleBase;
import com.tencent.mtt.hippy.uimanager.HippyViewController;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ExamplePackages implements HippyPackage
{
    @Override
    public Map<Class<? extends HippyNativeModuleBase>, Provider<? extends     HippyNativeModuleBase>> getNativeModules(final HippyEngineContext context)
    {
        Map<Class<? extends HippyNativeModuleBase>, Provider<? extends HippyNativeModuleBase>> modules = new HashMap<>();

        // regist the LogModule
        modules.put(ToastModule.class, new Provider<HippyNativeModuleBase>()
        {
            @Override
            public HippyNativeModuleBase get()
            {
                return new TestModule(context);
            }
        });

        return modules;
    }

注意事项

扩展Module中不能同步执行耗时操作,这可能卡住整个引擎通信线程。存在耗时场景,请使用异步线程处理。

混淆说明

扩展 Module 的类名和扩展方法名不能混淆,可以增加混淆例外。

-keep class * extends com.tencent.mtt.hippy.modules.nativemodules.HippyNativeModuleBase{ public *;}