FinClip为企业提供小程序生态圈技术产品,开发者可在FinClip小程序开发帮助中心找到相关FinClip小程序指引

# API/组件自定义

如果小程序里需要调用一些宿主 App 提供的能力,而 FinClip 小程序 SDK 未实现或无法实现时,就可以通过注册自定义 API 来实现,使得小程序里也能够调用 App 中注册的 API 了。

当然,要使用一些未实现或无法实现的组件时,也可以注册自定义组件。

注册自定义 API 分两个场景:

  1. 注册给原生小程序使用的自定义 API;
  2. 注册给小程序中 WebView 组件加载的 H5 使用的自定义 API。

# 1. 自定义小程序API

注册自定义小程序api以及使用自定义小程序api有四步:

  • 1.实现自定义api
  • 2.注册自定义api
  • 3.在小程序配置中声明自定义api
  • 4.小程序中调用自定义api

# 1.1 注册自定义小程序异步API

1)实现自定义异步api。

# 实现自定义小程序异步api示例
public class CustomApi extends BaseApi {

    public CustomApi(Context context) {
        super(context);
    }

    @Override
    public String[] apis() {
        return new String[]{"customEvent"}; //api名称
    }

    @Override
    public void invoke(String event, JSONObject param, ICallback callback) {
        // 调用方法时原生对应的操作
    }
}

2)将其注册到extensionApiManager中,支持单个注册和批量注册。

注册单个自定义api

    批量注册自定义api

      3)在小程序配置文件中声明自定义api。

      在小程序根目录创建 FinClipConf.js 并进行相应的自定义api配置,或通过 loadExtApi 传入配置参数

      module.exports = {
        extApi:[
          { //普通交互API
            name: 'finclipLogin', //扩展api名 该api必须Native方实现了
            sync: false, //是否为同步api
            params: { //扩展api 的参数格式,可以只列必须的属性
              url: ''
            }
          },
          {
              name: 'finclipTestSync',
              sync: true, // 是否为同步api
              params: {
                  name:'',
                  title:''
              }
          }
        ]
      }
      

      小程序端更多配置信息可参考 ft.loadExtApi

      4)小程序里调用自定义小程序异步api

      ft.finclipLogin({
          url:'https://www.baidu.com',
          success: function (res) {
              console.log("调用customEvent success");
              console.log(res);
          },
          fail: function (res) {
              console.log("调用customEvent fail");
              console.log(res);
          }
      });
      

      # 1.2 注册自定义小程序同步API

      同步api是指在调用的时候可以同步返回结果的自定义api。

      注意:自定义同步api需要继承SyncApi,并重写同步返回的invoke方法。 同步api必须在小程序进程注册才能生效

      1)实现自定义同步api。

      public class CustomApi extends SyncApi {
      
          public CustomApi(Context context) {
              super(context);
          }
      
          @Override
          public String[] apis() {
              return new String[]{"customApi"};
          }
      
          @Nullable
          @Override
          public String invoke(String event, JSONObject param) {
              // {"errMsg": "customApi:ok" , "data": "1"}  // 返回的数据格式是固定的,必须是个json格式且包含"errMsg": "customApi:ok" 这一段
              return getSuccessRes(event).put("data","1").toString(); // 可以借住sdk提供的api完成对数据的组装
              // return getFailureRes(event,"token miss").toString()
          }
      
      }
      

      2)在小程序进程注册同步api

        在小程序进程自定义同步API中,有两种方式获取小程序Activity:

        1. 外部传入,在自定义API类的构造方法中传入;
        2. 直接获取,可以通过FinAppProcessClient.appletProcessActivity获取当前小程序进程对应的Activity。

        3)在小程序配置文件中声明自定义api。

        在小程序根目录创建 FinClipConf.js 并进行相应的自定义api配置,或通过 loadExtApi 传入配置参数

        小程序端更多配置信息可参考 ft.loadExtApi

        module.exports = {
          extApi:[
            { //普通交互API
              name: 'finclipLogin', //扩展api名 该api必须Native方实现了
              sync: false, //是否为同步api
              params: { //扩展api 的参数格式,可以只列必须的属性
                url: ''
              }
            },
            {
                name: 'finclipTestSync',
                sync: true, // 是否为同步api
                params: {
                    name:'',
                    title:''
                }
            }
          ]
        }
        

        4)小程序里调用

        const res = ft.finclipTestSync({'name':'张三', 'title':'Finclip'});
        console.log(res.title);
        

        # 1.3 注册(含自定义sope权限的)自定义api

        自定义api时继承ScopeApi抽象类,示例如下:

        class CustomScopeApi(context: Context) : ScopeApi(context) {
        
            companion object {
                private const val METHOD_LOGIN = "customMethod"
            }
        
            override fun apis(): Array<String> {
                return arrayOf(METHOD_LOGIN)
            }
            
            // 返回绑定的scope对象
            override fun getBindScopes(): Array<AppletScopeBean> {
                // 此处构建自定义的scope对象
                val scope = AppletScopeBean(
                    // 唯一scope值
                    "scope.customScope",
                    // 名字
                    context.getString(R.string.custom_scope_name),
                    // 标题
                    context.getString(R.string.custom_scope_title),
                    // 描述
                    context.getString(R.string.custom_scope_desc)
                )
                return arrayOf(scope)
            }
        
            override fun invoke(event: String, params: JSONObject, callback: ICallback) {
                // 调用checkScope方法会对getBindScopes()方法内返回的自定义Scope权限进行检测、申请
                checkScope(object : Callback {
                    override fun onScopeCallback(allow: Boolean, msg: String) {
                        if (allow) {
                            // 权限申请成功,根据自己需要处理业务逻辑并回调给小程序
                            val result = JSONObject()
                            callback.onSuccess(result)
                        } else {
                            // 权限申请失败,根据自己需要处理业务逻辑并回调给小程序
                            val result = JSONObject()
                            result.put("msg", msg)
                            callback.onFail(result)
                        }
                    }
                })
            }
        }
        

        # 1.4 取消注册小程序API

        支持单个取消注册和批量取消注册。 自定义

        取消注册的某个api

        # 调用示例

          批量取消注册的api

          # 调用示例

            # 1.5 获取所有已注册的自定义小程序API

            # API

            /**
             * 获取所有已注册的小程序API
             */
            fun getRegisteredApis(): Map<String, IApi>
            

            # 调用示例

              # 2. 自定义 WebView 组件API

              小程序里加载的H5,如果也想调用宿主API的某个能力,就可以利用该方法注册一个API。 目前仅支持注册异步api。

              注册自定义webView Api和使用webView Api有三步:

              • 1.实现自定义api
              • 2.注册自定义api。
              • 3.H5中调用自定义api。

              # 2.1 注册WebView 组件API

              1. 实现自定义api。
              # 自定义api示例
              public class WebApi extends BaseApi {
              
                  public WebApi(Context context) {
                      super(context);
                  }
              
                  @Override
                  public String[] apis() {
                      return new String[]{"webApiName"}; //api名称
                  }
              
                  @Override
                  public void invoke(String event, JSONObject param, ICallback callback) {
                      // 调用方法时原生对应的操作
                  }
              }
              
              1. 将其注册到extensionWebApiManager中,支持单个注册和批量注册。

              注册单个自定义api

                批量注册自定义api

                  3)在H5内调用自定义api

                  在H5内引用我们的桥接JSSDK文件,即可调用上面的注册的方法了。

                  HTML内调用注册的方法示例:

                  window.ft.miniProgram.callNativeAPI('js2AppFunction', {name:'getLocation'}, (result) => {
                      console.log(result)
                  });
                  

                  # 2.2 取消注册 WebView 组件API

                  支持单个取消注册和批量取消注册。

                  取消单个WebView 组件API

                  # 调用示例

                    批量取消WebView 组件API

                      # 2.3 获取所有已注册的小程序 WebView API

                      # API

                      /**
                       * 获取所有已注册的网页调用的原生API
                       */
                      fun getRegisteredApis(): Map<String, IApi>
                      

                      # 调用示例

                        # 3. 在小程序进程中注册api

                        正常情况下注册到小程序的api是在主进程调用执行的,当有需要在小程序进程执行的api的时候,需要调用另外的接口去注册。

                          # 4. 原生调用 JS API

                          # API

                          /**
                           * 原生调用JS函数
                           *
                           * @param appId 小程序id
                           * @param funcName JS函数名
                           * @param funcParams JS函数参数
                           * @param webViewId WebView的id
                           * @param callback 回调
                           */
                          fun callJS(appId: String, funcName: String?, funcParams: String?, webViewId: Int, callback: FinCallback<String?>)
                          

                          # 调用示例

                            首先,在H5内引用我们的桥接JSSDK文件。

                            然后,在HTML里注册好方法,比如方法名叫app2jsFunction

                            window.ft.registNativeAPIHandler('app2jsFunction', function(res) {
                                // app2jsFunction callback
                            })
                            

                            # 5. 注册原生组件

                            由于资源有限,livePusher 和livePlayer等原生组件的实现可能需要借助外部的第三方控件,这时候就可以注册原生组件。我们现在支持注册的原生组件有三个:Camera、LivePlayer、LivePusher。

                            # 5.1 实现自定义的原生组件

                            实现INativeView接口

                            # 示例
                            class TestNativeView : INativeView {
                            
                                lateinit var eventChannel: INativeView.EventChannel
                            
                                /**
                                 * 创建nativeview
                                 * @param params 小程序中传来的参数
                                 * @param eventChannel 用来向小程序组件发送事件
                                 * @return 创建的view,会填充到小程序里声明组件的位置
                                 */
                                override fun onCreateView(
                                    context: Context,
                                    params: ShowNativeViewParams,
                                    eventChannel: INativeView.EventChannel
                                ): View {
                                    Log.d(TAG, "onCreateView:${params.nativeViewId}")
                                    this.eventChannel = eventChannel
                                    return TextView(context).apply {
                                        gravity = Gravity.CENTER
                                        setTextColor(Color.RED)
                                        text = params.params.toString()
                                        setBackgroundColor(Color.GREEN)
                                        setOnClickListener {
                                            eventChannel.send(
                                                "test",
                                                mapOf("time" to System.currentTimeMillis())
                                            )
                                        }
                                    }
                                }
                            
                                /**
                                 * 更新nativeview
                                 * @param params 小程序中传来的参数
                                 * @param view 之前创建的view
                                 */
                                override fun onUpdateView(context: Context, params: ShowNativeViewParams, view: View) {
                                    Log.d(TAG, "onUpdateView:${params.nativeViewId}")
                                    params.params?.let { (view as TextView).text = it.toString() }
                                }
                            
                            
                                /**
                                 * 销毁nativeview
                                 * @param params 小程序中传来的参数
                                 * @param view 之前创建的view
                                 */
                                override fun onDestroyView(context: Context, nativeViewId: String, view: View) {
                                    Log.d(TAG, "onDestroyView:$nativeViewId")
                                }
                            
                            }
                            

                            # 5.2 注册原生组件

                            # API
                            /**
                             * 注册原生组件
                             *
                             * @param type 组件类型
                             * @param cls 组件实现类 需实现INativeView接口
                             */
                            fun registerNativeView(type: String, cls: Class<out INativeView>)
                            
                            # 调用示例
                            # ·Kotlin
                            FinAppClient.nativeViewManager.registerNativeView("video", TestNativeView::class.java) 
                            
                            © 2022 FinClip with ❤