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

# Android API

这里介绍 FinClip 小程序 SDK 提供了哪些能力,以及API的详细说明和使用示例。

# 1. 基础API

# 1.1 SDK初始化

在使用小程序的API之前,需要先初始化小程序SDK。只有成功初始化之后,才能使用SDK提供的API,否则API都无法调用。

# API

/**
 * 初始化小程序SDK
 *
 * @param application  [android.app.Application]实例
 * @param finAppConfig [FinAppConfig]实例,小程序框架的配置信息
 * @param finCallback 初始化状态回调接口
 */
fun init(application: Application, finAppConfig: FinAppConfig, finCallback: FinCallback<Any?>?)

# 调用示例

# ·Kotlin
val config = FinAppConfig.Builder()
    .setAppKey("SDK Key")
    .setAppSecret("SDK Secret")
    .setApiUrl("服务器地址")
    .setApiPrefix("服务器接口请求路由前缀")
    .build()
FinAppClient.init(application, config, object : FinCallback<Any?> {
    override fun onSuccess(result: Any?) {
    }

    override fun onProgress(status: Int, info: String?) {
    }

    override fun onError(code: Int, error: String?) {
    }
})
# ·Java
FinAppConfig config = new FinAppConfig.Builder()
        .setAppKey("SDK Key")
        .setAppSecret("SDK Secret")
        .setApiUrl("服务器地址")
        .setApiPrefix("服务器接口请求路由前缀")
        .build();
FinAppClient.INSTANCE.init(this, config, new FinCallback<Object>() {
    @Override
    public void onSuccess(Object result) {
    }

    @Override
    public void onError(int code, String error) {
        Toast.makeText(SampleApplication.this, "SDK初始化失败", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onProgress(int status, String info) {

    }
});

注意

  1. 2.13.102版本开始,FinClip SDK 支持配置多个服务器信息,可以同时打开多个不同服务器上的小程序,所以我们提供了配置多个服务器信息的方式。
  2. Builder().setAppKeyBuilder().setAppSecret方式初始化单服务器的方法未来可能会禁用,请优先使用多服务器初始化的方式。
// 服务器信息集合
List<FinStoreConfig> storeConfigs = new ArrayList<>();

// 服务器1的信息
FinStoreConfig storeConfig1 = new FinStoreConfig(
        "SDK Key信息",   // SDK Key
        "SDK Secret信息",   // SDK Secret
        "服务器1的地址",   // 服务器地址
        "服务器1的数据上报服务器地址",   // 数据上报服务器地址
        "/api/v1/mop/",   // 服务器接口请求路由前缀
        "", // SDK指纹
        "加密方式"   // 加密方式,国密:SM,md5: MD5
);
storeConfigs.add(storeConfig1);

// 服务器2的信息
FinStoreConfig storeConfig2 = new FinStoreConfig(
        "SDK Key信息",   // SDK Key
        "SDK Secret信息",   // SDK Secret
        "服务器2的地址",   // 服务器地址
        "服务器2的数据上报服务器地址",   // 数据上报服务器地址
        "/api/v1/mop/",   // 服务器接口请求路由前缀
        "",  // SDK指纹
        "加密方式"   // 加密方式,国密:SM,md5: MD5
);
storeConfigs.add(storeConfig2);

FinAppConfig config = new FinAppConfig.Builder()
        .setFinStoreConfigs(storeConfigs) // 服务器信息集合
        .build();

# 1.2 打开小程序

打开小程序,其实是有两个场景:

  1. 普通的打开小程序,这里一般只需要小程序id和服务器地址即可,只能打开上架的线上版本小程序;
  2. 加密信息打开小程序,这个场景是扫描小程序平台上的二维码,得到二维码里的内容,然后使用二维码里的info(即加密信息)打开小程序。

# 1.2.1 普通打开小程序

打开小程序时,会先判断本地是否有缓存的小程序,如果没有,则会自动从远程服务器上下载小程序,然后打开。如果有缓存的小程序,则会先打开本地小程序,然后在后台校验服务器端是否有新版本。

如果有,则下载新版小程序,下次打开时,就会使用新版小程序;如果没有新版本,则什么也不做。

# API
/**
 * 启动小程序
 *
 * @param appId 小程序id
 */
fun startApplet(context: Context, appId: String)
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.startApplet(context, "appId")
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().startApplet(this, "appId");

# 1.2.2 普通打开小程序时携带启动参数

# API
/**
 * 启动小程序
 *
 * @param context 上下文
 * @param appId 小程序id
 * @param startParams 启动小程序时携带的参数
 */
fun startApplet(context: Context, appId: String, startParams: Map<String, String>)
# 调用示例
# ·Kotlin
val params = HashMap<String, String>()
// path为小程序页面路径
params["path"] = "/pages/index/index"
// query为启动参数,内容为"key1=value1&key2=value2 ..."的形式
params["query"] = "aaa=\"test\"&bbb=\"123\""
FinAppClient.appletApiManager.startApplet(this, "appId", params)
# ·Java
Map<String, String> params = new HashMap<>();
// path为小程序页面路径
params.put("path", "/pages/index/index");
// query为启动参数,内容为"key1=value1&key2=value2 ..."的形式
params.put("query", "aaa=\"test\"&bbb=\"123\"");
FinAppClient.INSTANCE.getAppletApiManager().startApplet(this, "appId", params);

# 1.2.3 普通打开小程序时携带服务器信息和启动参数

# API
/**
 * 启动小程序
 *
 * @param context 上下文
 * @param apiServer 小程序所在应用市场的服务器地址
 * @param appId 小程序id
 * @param sequence 小程序开发版本号
 * @param startParams 启动小程序时携带的参数
 */
fun startApplet(context: Context, apiServer: String, appId: String, sequence: Int? = null, startParams: FinAppInfo.StartParams? = null)
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.startApplet(this,  "https://finclip.com","finclip",null,FinAppInfo.StartParams("/pages/tweet/tweet","aaa=\"test\"&bbb=\"123\"",""))
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().startApplet(this,  "https://finclip.com","finclip",null, new FinAppInfo.StartParams("/pages/tweet/tweet","aaa=\"test\"&bbb=\"123\"",""));

# 1.2.4 二维码打开小程序

扫描平台中的小程序二维码,将解析出来的小程序二维码内容传给接口打开小程序。

# API
/**
 * 二维码启动小程序
 * @param context 上下文
 * @param qrCode 二维码内容
 * @param callback 启动结果回调
 */
fun startAppletByQrcode(context: Context, qrCode: String, callback: FinCallback<String>?)
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.startAppletByQrcode(
    this,
    "qrCode",
    object : FinSimpleCallback<String>() {
        override fun onSuccess(result: String) {
            // 启动成功
        }

        override fun onError(code: Int, error: String?) {
            // 启动失败
        }
    }
)
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().startAppletByQrcode(this, "qrCode", new FinSimpleCallback<String>() {
    @Override
    public void onSuccess(String result) {
        // 启动成功
    }

    @Override
    public void onError(int code, String error) {
        // 启动失败
    }
});

# 1.3 关闭小程序

由于SDK使用多进程的方式加载小程序,该API并不会真正结束小程序,而是将小程序移至系统后台。

# 1.3.1 关闭单个小程序

# API
/**
 * 关闭小程序
 *
 * @param appId 小程序id
 */
fun closeApplet(appId: String)
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.closeApplet("appId")
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().closeApplet(appId);

# 1.3.2 关闭所有小程序

# API
/**
 * 关闭所有小程序
 */
fun closeApplets()
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.closeApplets()
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().closeApplets();

# 1.4 结束小程序

# 1.4.1 结束单个小程序

# API
/**
 * 结束正在运行的小程序
 *
 * @param appId 小程序id
 */
fun finishRunningApplet(appId: String)
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.finishRunningApplet("appId")
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().finishRunningApplet("appId");

# 1.4.2 结束所有小程序

# API
/**
 * 结束所有正在运行的小程序
 */
fun finishAllRunningApplets()
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.finishAllRunningApplets()
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().finishAllRunningApplets();

# 1.5 删除小程序

由于会将小程序包和小程序信息缓存在本地,以后打开时速度会非常快。

所以,如果想要将小程序的所有信息都删除,那么可以调用以下api删除某个小程序或者删除所有小程序,删除的内容包括小程序本体、数据库、文件等。

# 1.5.1 删除单个小程序

# API
/**
 * 移除使用过的小程序
 *
 * @param appId 小程序id
 */
fun removeUsedApplet(appId: String)
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.removeUsedApplet("appId")
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().removeUsedApplet("appId");

# 1.5.2 删除所有小程序

# API
/**
 * 清除所有小程序相关数据(数据库、文件等)
 */
fun clearApplets()
# 调用示例
# ·Kotlin
FinAppClient.appletApiManager.clearApplets()
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().clearApplets();

# 1.6 搜索小程序

要搜索小程序,需要两步:

  1. 确保在初始化SDK的时候,配置了该服务器信息;
  2. 调用该搜索接口搜索小程序

# API

/**
 * 搜索小程序
 *
 * @param searchAppletRequest 请求体
 * @param callback 请求结果回调
 */
fun searchApplet(
    searchAppletRequest: SearchAppletRequest,
    callback: FinCallback<SearchAppletResponse>
)

SearchAppletRequest说明:

/**
 * 搜索小程序请求实体类
 *
 * @param apiServer 服务器地址
 * @param text 搜索内容
 */
data class SearchAppletRequest(var apiServer: String,
                               var text: String)

SearchAppletResponse说明:

/**
 * 搜索小程序返回实体类
 *
 * @param list 搜索到的小程序集合
 * @param total 搜索到的小程序数量
 */
data class SearchAppletResponse(
        val list: List<AppletInfo>?,
        val total: Int
)

/**
 * 搜索小程序返回的小程序信息实体类
 *
 * @param appId 小程序id
 * @param appName 小程序名称
 * @param desc 小程序描述信息
 * @param highLights 高亮字体
 * @param logo 小程序logo
 * @param organName 企业名称
 * @param pageUrl 小程序搜索到的页面路径
 * @param showText 展示内容
 */
data class AppletInfo(
        val appId: String?,
        val appName: String?,
        val desc: String?,
        val highLights: List<HighLight>?,
        val logo: String?,
        val organName: String?,
        val pageUrl: String?,
        val showText: String?
)

/**
 * 高亮字体
 *
 * @param key 高亮字体的key
 * @param value 高亮字体的value
 */
data class HighLight(
        val key: String?,
        val value: String?
)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.searchApplet(
    SearchAppletRequest("服务地地址", "搜索内容"),
    object : FinCallback<SearchAppletResponse> {
        override fun onSuccess(result: SearchAppletResponse?) {
            // 搜索成功
        }

        override fun onError(code: Int, error: String?) {
            // 搜索失败
        }

        override fun onProgress(status: Int, info: String?) {
        }
    })
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().searchApplet(
        new SearchAppletRequest("服务器地址", "搜索内容"),
        new FinCallback<SearchAppletResponse>() {
            @Override
            public void onSuccess(SearchAppletResponse result) {
                // 搜索成功
            }

            @Override
            public void onError(int code, String error) {
                // 搜索失败
            }

            @Override
            public void onProgress(int status, String info) {

            }
        });

# 1.7 获取小程序对象信息

# API

/**
 * 获取小程序信息
 */
fun getAppletInfo(appId: String): FinAppInfo?

# 调用示例

# ·Kotlin
val appInfo = FinAppClient.appletApiManager.getAppletInfo("appId")
# ·Java
FinAppInfo appInfo = FinAppClient.INSTANCE.getAppletApiManager().getAppletInfo("appId"); 

# 相关字段说明

字段名 说明
appId 小程序id
codeId 小程序代码包ID
userId 小程序开发者id
appAvatar 小程序头像
appTitle 小程序标题
appDescription 小程序描述
appPath 小程序路径
appVersion 小程序版本号
appVersionDescription 小程序版本说明
sequence 小程序序列
isGrayVersion 是否是灰度版本
appThumbnail 小程序缩略图
groupId 所属组织ID
groupName 所属组织名称
appType 小程序类型
createdBy 小程序开发者
createdTime 小程序创建时间
startParams 启动参数
info 扩展信息
fromAppId 小程序的来源小程序id
如果小程序A通过调用navigateToMiniProgram打开小程序B,那么对于小程序B来说,fromAppId为小程序A的appId
finStoreConfig 小程序应用市场配置信息
frameworkVersion 基础库版本号
url 小程序下载地址
md5 小程序整包MD5
cryptInfo 小程序加密信息

# 1.8 获取小程序当前WebView信息

# 1.8.1 获取当前webView的URL

FinAppClient.appletApiManager.getCurrentWebViewURL(
    object : FinCallback<String> {
        override fun onSuccess(result: String?) {
            toast("url:$result")
        }

        override fun onError(code: Int, error: String?) {

        }

        override fun onProgress(status: Int, info: String?) {

        }
    })

# 1.8.2 获取当前webView的UserAgent

FinAppClient.appletApiManager.getCurrentWebViewUserAgent(
    object : FinCallback<String> {
        override fun onSuccess(result: String?) {
            toast("userAgent:$result")
        }

        override fun onError(code: Int, error: String?) {

        }

        override fun onProgress(status: Int, info: String?) {

        }
    })

# 1.9 获取小程序页面截图

# API

/**
 * 获取小程序页面截图
 *
 * @param appId 小程序id
 * @param callback 小程序页面截图回调
 */
fun captureAppletPicture(appId: String, callback: FinCallback<Bitmap?>)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.captureAppletPicture(
    "appId",
    object : FinCallback<Bitmap?> {
        override fun onSuccess(result: Bitmap?) {
            Log.d(TAG, "获取小程序页面截图成功 :$result")
        }

        override fun onError(code: Int, error: String?) {
            Log.e(TAG, "获取小程序页面截图失败 :$code, $error")
        }

        override fun onProgress(status: Int, info: String?) {
        }
    })
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().captureAppletPicture(
        "appId",
        new FinCallback<Bitmap>() {
            @Override
            public void onSuccess(Bitmap result) {
                Log.d(TAG, "获取小程序页面截图成功 :" + bitmap);
            }

            @Override
            public void onError(int code, String error) {
                Log.e(TAG, "获取小程序页面截图失败 :" + code + ", " + error);
            }

            @Override
            public void onProgress(int status, String info) {

            }
        });

# 1.10 获取使用过的小程序

# 1.10.1 获取使用过的单个小程序

# API
/**
 * 获取指定小程序id的使用过的小程序
 *
 * @param appId 小程序id
 */
fun getUsedApplet(appId: String): FinApplet?
# 调用示例
# ·Kotlin
val finApplet = FinAppClient.appletApiManager.getUsedApplet("appId") 
# ·Java
FinApplet finApplet = FinAppClient.INSTANCE.getAppletApiManager().getUsedApplet("appId"); 

# 1.10.2 获取使用过的小程序列表

# API
/**
 * 获取所有使用过的小程序
 */
fun getUsedApplets(): List<FinApplet>
# 调用示例
# ·Kotlin
val usedApplets = FinAppClient.appletApiManager.getUsedApplets() 
# ·Java
List<FinApplet> usedApplets = FinAppClient.INSTANCE.getAppletApiManager().getUsedApplets(); 

# 1.11 微信小程序二维码信息转换为 FinClip小程序

该 API 的使用场景比较特别,当某小程序在微信和 FinClip 服务上都上架之后,可以在 FinClip 平台关联微信的小程序。这时FinClip平台上的线上版二维码,既可以用微信扫码打开,也可以用 FinClip APP 或其他集成了 FinClip SDK 的 APP 扫码打开。

流程是先扫描该二维码,得到二维码内容,然后调用该接口获取 FinClip 小程序 id,最后调用打开小程序的API即可。

# API

/**
 * 根据微信QrCode信息解析小程序信息
 *
 * @param qrCode 二维码信息
 * @param apiServer 小程序所在应用市场的服务器地址
 * @param callback 结果回调
 */
fun parseAppletInfoFromWXQrCode(
    qrCode: String,
    apiServer: String,
    callback: FinSimpleCallback<ParsedAppletInfo?>
)

ParsedAppletInfo结构如下:

/**
 * 根据微信QrCode信息解析小程序信息返回的小程序信息实体类
 *
 * @param appId 小程序id
 */
data class ParsedAppletInfo(
    val appId: String?
)

# 调用示例

# Kotlin
FinAppClient.appletApiManager.parseAppletInfoFromWXQrCode(
    qrCode,
    apiServer,
    object : FinSimpleCallback<ParsedAppletInfo?>() {
        override fun onSuccess(result: ParsedAppletInfo?) {
            Log.d(TAG, "parse onSuccess result : ${result.toString()}")
        }

        override fun onError(code: Int, error: String?) {
            Log.d(TAG, "parse onError code : $code, error : $error")
        }
    })
# Java
FinAppClient.INSTANCE.getAppletApiManager().parseAppletInfoFromWXQrCode(
        qrCode,
        apiServer,
        new FinSimpleCallback<ParsedAppletInfo>() {
            @Override
            public void onSuccess(ParsedAppletInfo result) {
                Log.d(TAG, "parse onSuccess result : " + result.toString());
            }

            @Override
            public void onError(int code, @org.jetbrains.annotations.Nullable String error) {
                Log.d(TAG, "parse onError code : " + code + ", error : " + error);
            }
        }
);

# 1.12 代理方法

小程序的部分功能,需要原生端去实现才能调用,比如转发和获取主体App的用户信息等。

这些代理方法都声明在[IAppletHandler]、[IAppletProcessHandler]抽象类中。

# API

/**
 * 设置[IAppletHandler]的实现类
 *
 * @param appletHandler [IAppletHandler]的实现类
 */
fun setAppletHandler(appletHandler: IAppletHandler)

/**
 * 设置[IAppletProcessHandler]的实现类
 *
 * @param appletProcessHandler [IAppletProcessHandler]的实现类
 */
fun setAppletProcessHandler(appletProcessHandler: IAppletProcessHandler)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.setAppletHandler(
    object : IAppletHandler {
        override fun shareAppMessage(
            appInfo: String,
            bitmap: Bitmap?,
            callback: IAppletHandler.IAppletCallback
        ) {

        }
    })

FinAppProcessClient.appletProcessApiManager.setAppletProcessHandler(
    object : IAppletProcessHandler {
        override fun onNavigationBarMoreButtonClicked(
            context: Context,
            appId: String
        ): Boolean {
            return true // 返回true表示自行处理"更多"按钮点击事件,屏蔽默认菜单显示逻辑。
        }
    })
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().setAppletHandler(new IAppletHandler() {
    @Override
    public void shareAppMessage(@NotNull String appInfo,
                                @Nullable Bitmap bitmap,
                                @NotNull IAppletCallback callback) {

    }
});

FinAppProcessClient.INSTANCE.getAppletProcessApiManager().setAppletProcessHandler(new IAppletProcessHandler(){
    @Override
    public boolean onNavigationBarMoreButtonClicked(@NonNull Context context, @NonNull String appId) {
        return true; // 返回true表示自行处理"更多"按钮点击事件,屏蔽默认菜单显示逻辑。
    }
});

注意

  • FinAppProcessClient类需要在小程序进程使用。

    请使用FinAppClient.INSTANCE.isFinAppProcess()方法判断是否处于小程序进程

  • IAppletProcessHandler接口方法在小程序进程执行。

# 1.13 把finfile文件路径转换为绝对路径

    /**
     *  把finfile文件路径转换为绝对路径
     *  @param context
     *  @param appId
     *  @param filePath  finfile文件路径
     */
    fun getFinFileAbsolutePath(context: Context, appId: String, filePath: String): String?

# 调用示例

# ·Kotlin
val appletTempPath = FinAppClient.appletApiManager.getFinFileAbsolutePath(this,"60964a900f0ca30001292da1","finfile://tmp_sss.jpg")

# 1.14.1 获取小程序临时文件存储目录的路径

# API

/**
 * 获取小程序临时文件存储目录的路径
 *
 * @param context 上下文
 * @param appId 小程序ID
 * @return 小程序临时文件存储目录的路径
 */
fun getAppletTempPath(context: Context, appId: String): String?

# 调用示例

# ·Kotlin
val appletTempPath = FinAppClient.appletApiManager.getAppletTempPath(this, "appId")
# ·Java
String appletTempPath = FinAppClient.INSTANCE.getAppletApiManager().getAppletTempPath(this, "appId");

# 1.14.2 获取小程序源码存储目录的路径

# API

/**
 * 获取小程序源码存储目录的路径
 *
 * @param context 上下文
 * @param appId 小程序ID
 * @return 小程序源码存储目录的路径
 */
fun getAppletSourcePath(context: Context, appId: String): String?

# 调用示例

# ·Kotlin
val appletSourcePath = FinAppClient.appletApiManager.getAppletSourcePath(context, "appId")
# ·Java
String appletSourcePath = FinAppClient.INSTANCE.getAppletApiManager().getAppletSourcePath(context, appId);

# 1.15 设置小程序Activity的切换动画

# API

/**
 * 设置小程序Activity的切换动画
 *
 * @param anim [Anim]动画
 */
fun setActivityTransitionAnim(anim: Anim)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.setActivityTransitionAnim(SlideFromRightToLeftAnim)
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().setActivityTransitionAnim(SlideFromRightToLeftAnim.INSTANCE);

# 1.16 原生发送事件给小程序

# API

/**
 * 原生发送事件给小程序
 * @param appId
 * @param params 事件参数
 */
fun sendCustomEvent(appId: String, params: String)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.sendCustomEvent("app", "{\"test\":\"123\"}")
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().sendCustomEvent("app", "{\"test\":\"123\"}")

# 1.17 设置[IAppletLifecycleCallback]

# API

/**
 * 设置[IAppletLifecycleCallback]
 *
 * @param appletLifecycleCallback [IAppletLifecycleCallback]对象
 */
fun setAppletLifecycleCallback(appletLifecycleCallback: IAppletLifecycleCallback)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.setAppletLifecycleCallback(object : IAppletLifecycleCallback {
     override fun onCreate(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onCreate : $appId")
    }

    override fun onInitComplete(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onInitComplete : $appId")
    }

    override fun onStart(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onStart : $appId")
    }

    override fun onResume(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onResume : $appId")
    }

    override fun onPause(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onPause : $appId")
    }

    override fun onStop(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onStop : $appId")
    }

    override fun onDestroy(appId: String) {
        Log.d(TAG, "IAppletLifecycleCallback onDestroy : $appId")
    }

    override fun onFailure(appId: String, errMsg: String) {
        Log.d(TAG, "IAppletLifecycleCallback onFailure : $appId ,$errMsg")
    }
})
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().setAppletLifecycleCallback(new IAppletLifecycleCallback() {

    @Override
    public void onCreate(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onCreate : " + appId);
    }
    
    @Override
    public void onInitComplete(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onInitComplete : " + appId);
    }

    @Override
    public void onStart(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onStart : " + appId);
    }

    @Override
    public void onResume(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onResume : " + appId);
    }

    @Override
    public void onPause(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onPause : " + appId);
    }

    @Override
    public void onStop(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onStop : " + appId);
    }

    @Override
    public void onDestroy(@NotNull String appId) {
        Log.d(TAG, "IAppletLifecycleCallback onDestroy : " + appId);
    }

    @Override
    public void onFailure(@NotNull String appId, String errMsg) {
        Log.d(TAG, "IAppletLifecycleCallback onFailure : " + appId);
    }
});

# 1.18 创建一个[FinAppletWebView]实例

改方法已于2.12.4版本废弃,若需要用到FinAppletWebView,直接实例化该类即可。

# API

/**
 * 创建一个[FinAppletWebView]实例
 *
 * @param context [Context]对象
 * @return 一个[FinAppletWebView]实例
 */
fun createFinAppletWebView(context: Context): FinAppletWebView

# 调用示例

# ·Kotlin
val finAppletWebView = FinAppClient.appletApiManager.createFinAppletWebView(this)
# ·Java
FinAppletWebView finAppletWebView = FinAppClient.INSTANCE.getAppletApiManager().createFinAppletWebView(context);

# 1.19 获取当前小程序的id

# API

/**
 * 获取当前小程序的id
 */
fun getCurrentAppletId(): String?

# 调用示例

# ·Kotlin
val currentAppletId = FinAppClient.appletApiManager.getCurrentAppletId() 
# ·Java
String currentAppletId = FinAppClient.INSTANCE.getAppletApiManager().getCurrentAppletId(); 

# 1.20 判断是否是使用过的小程序

# API

/**
 * 判断是否是使用过的小程序
 */
fun isUsedApplet(appId: String): Boolean

# 调用示例

# ·Kotlin
val isUsedApplet = FinAppClient.appletApiManager.isUsedApplet("appId") 
# ·Java
boolean isUsedApplet = FinAppClient.INSTANCE.getAppletApiManager().isUsedApplet("appId"); 

# 1.21 跨进程调用接口

# 1.21.1 主进程调用小程序进程

调用 需要在主进程调用

FinAppClient.appletApiManager.callInAppletProcess(
        FinAppClient.appletApiManager.getCurrentAppletId().orEmpty(),
        "主进程调用小程序进程方法名",
        "主进程调用小程序进程参数",
        object : FinCallback<String> {
            override fun onSuccess(result: String?) {
                toast("小程序进程返回的结果:$result")
            }

            override fun onError(code: Int, error: String?) {

            }

            override fun onProgress(status: Int, info: String?) {

            }
        })

接收 需要在小程序进程注册处理方法 可通过FinAppClient.isFinAppProcess(context)判断是否是小程序进程

if (FinAppClient.isFinAppProcess(this)) {
    FinAppProcessClient.appletProcessApiManager.setMainProcessCallHandler(
        object : IAppletProcessApiManager.MainProcessCallHandler {
            override fun onMainProcessCall(
                name: String,
                params: String?,
                callback: IApiCallback?
            ) {
                toast("主进程调用小程序进程:name:$name,params:$params")
                callback?.onSuccess("返回结果给主进程")
            }
        })
}

# 1.21.2 小程序进程调用主进程

调用 需要在小程序进程调用

FinAppProcessClient.appletProcessApiManager.callInMainProcess(
    "小程序进程调用主进程的方法名",
    "小程序进程调用主进程的参数",
    object : FinCallback<String> {
        override fun onSuccess(result: String?) {
            toast("小程序进程调用主进程成功:$result")
        }

        override fun onError(code: Int, error: String?) {

        }

        override fun onProgress(status: Int, info: String?) {

        }
    })

接收 需要在主进程注册处理方法

FinAppClient.appletApiManager.setAppletProcessCallHandler(
    object : IAppletApiManager.AppletProcessCallHandler {
        override fun onAppletProcessCall(
            name: String,
            params: String?,
            callback: IApiCallback?
        ) {
            application.toast("小程序进程调用主进程:name:$name,params:$params")
            callback?.onSuccess("返回结果给小程序进程")
        }
    })

# 1.22 在小程序进程调用api

FinAppClient.appletApiManager只能在主进程中使用

在小程序进程中要使用FinAppProcessClient.appletProcessApiManager之中的方法。

 FinAppProcessClient.appletProcessApiManager.getCurrentAppletId()

 FinAppProcessClient.appletProcessApiManager.getAppletInfo()

 FinAppProcessClient.appletProcessApiManager.sendCustomEvent(params)

# 1.23 设置最大可运行的小程序个数

该接口可以设置最大可运行的小程序个数,当打开的小程序超过最大可运行个数时,最先打开的小程序会被回收。

注意

最大可运行的小程序个数默认为5个,可设置的范围为1-5,设置<=0或>5的数字不生效

val config = FinAppConfig.Builder()
    .setSdkKey("SDK Key")
    .setSdkSecret("SDK Secret")
    .setMaxRunningApplet(3) //设置最大可运行的小程序个数
    .build()

FinAppClient.init(application, config, object : FinCallback<Any?> {})

# 1.24 设置前台服务保持app运行

当打开小程序后,app进入后台运行。这时app可能会被系统杀死。可以配置通过启动前台服务一直保持app运行而不被系统杀死

val config = FinAppConfig.Builder()
    .setSdkKey(BuildConfig.SDK_KEY)
    .setSdkSecret(BuildConfig.SDK_SECRET)
    .setForegroundServiceConfig(
        FinAppConfig.ForegroundServiceConfig(
            true, //是否开启前台服务
            R.drawable.ic_launcher, //前台服务的icon
            "小程序正在运行", // 前台服务的标题
            "",
            notificationChannelId, // 通知channelId
            notificationChannelName, // 通知channel名称
            notificationChannelDesc, // 通知channel介绍
        )
    )
    .build()

FinAppClient.init(application, config, object : FinCallback<Any?> {})

# 1.25 设置当主进程关闭的时候小程序进程也关闭

默认情况下,当app主进程关闭的时候,小程序依然可以独立运行。可以配合当app进程关闭或被杀死的时候小程序进程也被关闭

val config = FinAppConfig.Builder()
                .setSdkKey(BuildConfig.SDK_KEY)
                .setSdkSecret(BuildConfig.SDK_SECRET)
                .setBindAppletWithMainProcess(true) //当主进程关闭的时候小程序进程也关闭
                .setKillAppletProcessNotice("APP已被关闭,小程序无法单独使用,请您重新打开APP再使用小程序。")
                .build()

FinAppClient.init(application, config, object : FinCallback<Any?> {})

# 1.26 配置小程序右上角胶囊样式

val uiConfig = UIConfig()
uiConfig.setCapsuleConfig(CapsuleConfig())

# 胶囊配置属性介绍

public static class CapsuleConfig {
        /**
         *  右上角胶囊视图的宽度,默认值为88
         * 
         */
        public float capsuleWidth = 88;
    
        /**
         *  右上角胶囊视图的高度,默认值为32
         * 
         */
        public float capsuleHeight = 32;
    
        /**
         * 右上角胶囊视图的右边距
         */
        public float capsuleRightMargin = 7;
    
        /**
         *  右上角胶囊视图的圆角半径,默认值为5
         * 
         */
        public float capsuleCornerRadius = 5;
    
        /**
         *  右上角胶囊视图的边框宽度,默认值为0.8
         * 
         */
        public float capsuleBorderWidth = 1f;
    
        /**
         * 胶囊背景颜色浅色
         */
        public int capsuleBgLightColor = 0x33000000;
    
        /**
         * 胶囊背景颜色深色
         */
        public int capsuleBgDarkColor = 0x80ffffff;
    
        /**
         *  右上角胶囊视图的边框浅色颜色
         * 
         */
        public int capsuleBorderLightColor = 0x80ffffff;
    
        /**
         *  右上角胶囊视图的边框深色颜色
         * 
         */
        public int capsuleBorderDarkColor = 0x26000000;
    
        /**
         * 胶囊分割线浅色颜色
         */
        public int capsuleDividerLightColor = 0x80ffffff;
    
        /**
         * 胶囊分割线深色颜色
         */
        public int capsuleDividerDarkColor = 0x26000000;
    
        /**
         *  胶囊里的浅色更多按钮的图片对象,如果不传,会使用默认图标
         * 
         */
        public int moreLightImage = R.drawable.miniapps_more_light;
    
        /**
         *  胶囊里的深色更多按钮的图片对象,如果不传,会使用默认图标
         *  
         */
        public int moreDarkImage = R.drawable.miniapps_more_dark;
    
        /**
         *  胶囊里的更多按钮的宽度,高度与宽度相等
         * 
         */
        public float moreBtnWidth = 32;
    
        /**
         *  胶囊里的更多按钮的左边距
         * 
         */
        public float moreBtnLeftMargin = 6;
    
        /**
         *  胶囊里的浅色更多按钮的图片对象,如果不传,会使用默认图标
         * 
         */
        public int closeLightImage = R.drawable.miniapps_close_light;
    
        /**
         *  胶囊里的深色更多按钮的图片对象,如果不传,会使用默认图标
         * 
         */
        public int closeDarkImage = R.drawable.miniapps_close_dark;
    
        /**
         *  胶囊里的关闭按钮的宽度,高度与宽度相等
         * 
         */
        public float closeBtnWidth = 32;
    
        /**
         *  胶囊里的关闭按钮的左边距
         * 
         */
        public float closeBtnLeftMargin = 6;
}

# 配置胶囊示例

uiConfig.capsuleConfig.apply {
    capsuleWidth = 86f
    capsuleHeight = 31f
    capsuleRightMargin = 15f
    capsuleCornerRadius = 15.5f
    capsuleBorderWidth = 0.5f
    capsuleBgLightColor = Color.TRANSPARENT
    capsuleBgDarkColor = Color.TRANSPARENT
    capsuleBorderLightColor = Color.parseColor("#88ffffff")
    capsuleBorderDarkColor = Color.parseColor("#a5a9b4")
    moreLightImage = R.drawable.more_light
    moreDarkImage = R.drawable.more_dark
    moreBtnWidth = 25f
    moreBtnLeftMargin = 11f
    closeLightImage = R.drawable.close_light
    closeDarkImage = R.drawable.close_dark
    closeBtnWidth = 25f
    closeBtnLeftMargin = 9f
    capsuleDividerLightColor = Color.parseColor("#88ffffff")
    capsuleDividerDarkColor = Color.parseColor("#a5a9b4")
}

# 1.27 配置导航栏返回首页按钮样式

val uiConfig = UIConfig()
uiConfig.setNavHomeConfig(NavHomeConfig())

目前返回首页按钮出现的条件为(需同时满足):

  1. 使用了默认导航栏样式(非 custom)。

  2. 不是首页或 tabbar 页面(在 app.json 中定义的)。

  3. 是页面栈最底层页面。

小程序可在 onShow 中调用 hideHomeButton() 手动隐藏返回首页按钮。

# 导航栏返回首页按钮样式属性介绍

public static class NavHomeConfig {
    /**
     * 导航栏返回首页按钮浅色图标,如果不传,会使用默认图标
     */
    public int lightImage = R.drawable.miniapps_home_light;
    /**
     * 导航栏返回首页按钮浅色图标,如果不传,会使用默认图标
     */
    public int darkImage = R.drawable.miniapps_home_dark;
    
    /**
     * 返回首页按钮宽度,默认44
     */
    public float width = 44;
    
    /**
     * 返回首页按钮高度,默认32
     */
    public float height = 32;
    
    /**
     * 返回首页按钮的左边距,默认7
     */
    public float leftMargin = 7;
    
    /**
     * 返回首页按钮边框圆角半径,默认5
     */
    public float cornerRadius = 5;
    
    /**
     * 返回首页按钮边框宽度,默认1
     */
    public float borderWidth = 1;
    
    /**
     * 返回首页按钮浅色边框颜色,默认0X80FFFFFF
     */
    public int borderLightColor = 0x80ffffff;
    
    /**
     * 返回首页按钮深色边框颜色,默认0X26000000
     */
    public int borderDarkColor = 0x26000000;
    
    /**
     * 返回首页按钮浅色背景,默认0x33000000
     */
    public int bgLightColor = 0x33000000;
    
    /**
     * 返回首页按钮深色背景,默认0x33000000
     */
    public int bgDarkColor = 0x80ffffff;
}

# 配置导航栏返回按钮样式示例

uiConfig.navHomeConfig.apply {
    width = 43f
    height = 31f
    leftMargin = 15f
    cornerRadius = 15.5f
    borderWidth = 0.5f
    bgLightColor = Color.TRANSPARENT
    bgDarkColor = Color.TRANSPARENT
    borderLightColor = Color.parseColor("#88ffffff")
    borderDarkColor = Color.parseColor("#a5a9b4")
    lightImage = R.drawable.home_light
    darkImage = R.drawable.home_dark
}

# 1.27 配置小程序浮窗运行

在一些大屏幕设备上,可以配置小程序以浮窗形式运行。以浮窗形式运行时,小程序固定为竖屏模式,浮窗位置和大小可以配置,位于浮窗下层的页面不可交互

// 设置悬浮模式后,同时要在sample styles.xml将FinAppletTheme覆盖为FinAppletTranslucentTheme

<!--悬浮模式需要覆盖FinAppletTheme主题为FinAppletTranslucentTheme-->
<style name="FinAppletTheme" parent="@style/FinAppletTranslucentTheme" />

# 浮窗配置属性介绍


        public static class FloatWindowConfig {
            
            public boolean floatMode = false;

            public int x;
            public int y;
            public int width;
            public int height;
        }

浮窗配置示例

uiConfig.floatWindowConfig.apply {
            floatMode = false
            width = 800
            height = 1400
            x = application.screenWidth() / 2 - width / 2
            y = application.screenHeight() / 2 - height / 2
        }

# 1.28 打开离线小程序

  1. 通过预置小程序包与基础库打开小程序

可以通过预置的小程序与基础库来打开小程序,加快小程序第一次加载时的速度。小程序与基础库压缩包需使用后台导出的固定格式的文件。

此接口离线包只在第一次加载没有缓存时生效,当有缓存时流程与正常打开在线小程序一致。

接口说明:

/**
 * 启动小程序
 *
 * @param context 上下文
 * @param apiServer 小程序所在应用市场的服务器地址
 * @param appId 小程序id
 * @param startParams 启动小程序时携带的参数
 * @param offlineLibraryPath 离线基础库路径
 * @param offlineAppletPath 本地小程序包的路径
 */
fun startApplet(context: Context, apiServer: String, appId: String, startParams: FinAppInfo.StartParams? = null, offlineLibraryPath: String, offlineAppletPath: String)

调用示例:

FinAppClient.appletApiManager.startApplet(this, "https://finchat-mop-b.finogeeks.club",
        "6177b98f95604100015ea8dc", null,
        "$filesDir/framework-2.11.4-alpha20211101v01.zip", "$filesDir/离线包-分包-1.1.1.zip")
  1. 打开离线小程序

此接口用来打开纯离线的小程序,接口为限制api,需要使用开启了离线功能的sdkkey与secret方可使用。

打开离线小程序需要离线的小程序包和小程序基础库信息。可以从FIDE 开发工具中导出 离线包的方式 获取。使用时直接传入导出离线包的路径

基础库需要凡泰单独提供

接口说明:

/**
 * 打开本地小程序
 * @param appId 小程序id
 * @param appTitle 小程序名称
 * @param appAvatar 小程序logo
 * @param appRuntimeDomain 小程序域名列表
 * @param packages 小程序分包信息
 * @param frameworkPath 基础库路径
 * @param frameworkUseCache 是否使用已缓存的基础库,如果选false,每次都会重新解压
 * @param appletPath 小程序路径
 * @param appletPassword 小程序压缩包密码
 * @param appletUseCache 是否使用已缓存的小程序
 *
 */
fun startLocalApplet(context: Context,
                     appId: String, appTitle: String?, appAvatar: String?,
                     appRuntimeDomain: AppRuntimeDomain?, packages: List<Package>?,
                     startParams: FinAppInfo.StartParams?,
                     frameworkPath: String, frameworkUseCache: Boolean,
                     appletPath: String, appletPassword: String, appletUseCache: Boolean
)

使用示例:

val appletPath = "$filesDir/miniprogram.zip"
val packages: List<Package> = Gson().fromJson(File("$filesDir/packageConfig.json").readText(), object : TypeToken<List<Package>>() {}.type)
val frameworkPath = "$filesDir/mop-framework-2.12.7.zip"
FinAppClient.appletApiManager.startLocalApplet(this, "6177b98f95604100015ea8d1", "场景二小程序修改名称", null, null, packages,
        FinAppInfo.StartParams("/pages/me/me",""), frameworkPath, false, appletPath, "", false)

# 1.29 配置小程序调试模式

val config = FinAppConfig.Builder()
				// 其它配置项省略
				.setEnableAppletDebug(true)
                .build()

FinAppClient.init(application, config, object : FinCallback<Any?> {})

是否开启全局小程序debug模式,设置为true后所有小程序都会显示vconsole,如果设置为false,则开发版、体验版、IDE预览版可通过更多菜单内的调试按钮开启Debug模式

# 2. 高级API

# 2.1 注册自定义API

如果小程序里需要调用一些宿主app提供的能力,而FinClip SDK未实现或无法实现时,就可以注册一些自定义API。然后小程序里就可以像调用其他API一样调用注册的API了。

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

# 2.1.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) {
        // 调用方法时原生对应的操作
    }
}

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

# 自定义同步api示例

同步api是指在调用的时候可以同步返回结果的自定义api,自定义同步api需要继承SyncApi,并重写同步返回的invoke方法

*** 同步api必须在小程序进程注册才能生效,参考 2.8 在小程序进程中注册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) {
        return "result";
    }

}
# ·Kotlin
# 单个注册
FinAppClient.extensionApiManager.registerApi(CustomApi(this)) 
# 批量注册
val apis = listOf<IApi>(CustomApi1(), CustomApi2(), CustomApi3())
FinAppClient.extensionApiManager.registerApis(apis) 
# ·Java
# 单个注册
FinAppClient.INSTANCE.getExtensionApiManager().registerApi(new CustomApi(this)); 
# 批量注册
List<IApi> apis = new ArrayList<>();

IApi customApi1 = new CustomApi1();
apis.add(customApi1);

IApi customApi2 = new CustomApi2();
apis.add(customApi2);

IApi customApi3 = new CustomApi3();
apis.add(customApi3);

FinAppClient.INSTANCE.getExtensionApiManager().registerApis(apis); 
# 在小程序中使用自定义api

在小程序中使用自定义api只需要两步:

  1. 在小程序根目录创建FinClipConf.js并进行相应的自定义api配置
  2. 在小程序中调用自定义api

FinClipConf.js的配置如下:

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

在小程序中,调用自定义api的方法如下:

ft.customEvent({
    url:'https://www.xxx.com',
    success: function (res) {
        console.log("customEvent call succeeded");
        console.log(res)
    },
    fail: function (res) {
        console.log("customEvent call failed");
        console.log(res)
    }
})

# 2.1.2 注册小程序 WebView 组件API

小程序里加载的H5,如果也想调用宿主API的某个能力,就可以利用该方法注册一个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) {
        // 调用方法时原生对应的操作
    }
}

然后将其注册到extensionWebApiManager中,支持单个注册和批量注册。

# ·Kotlin
# 单个注册
FinAppClient.extensionWebApiManager.registerApi(WebApi(this)) 
# 批量注册
val apis = listOf<IApi>(WebApi1(), WebApi2(), WebApi3())
FinAppClient.extensionWebApiManager.registerApis(apis)
# ·Java
# 单个注册
FinAppClient.INSTANCE.getExtensionWebApiManager().registerApi(new WebApi(this)); 
# 批量注册
List<IApi> apis = new ArrayList<>();

IApi webApi1 = new WebApi1();
apis.add(webApi1);

IApi webApi2 = new WebApi2();
apis.add(webApi2);

IApi webApi3 = new WebApi3();
apis.add(webApi3);

FinAppClient.INSTANCE.getExtensionWebApiManager().registerApis(apis); 

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

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

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

# 2.2 原生调用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?>)

# 调用示例

# ·Kotlin
FinAppClient.appletApiManager.callJS(
    "appId",
    "funcName",
    "funParams",
    1,
    object : FinCallback<String?> {
        override fun onSuccess(result: String?) {
            Log.d(TAG, "callJS onSuccess : $result")
        }

        override fun onError(code: Int, error: String?) {
            Log.d(TAG, "callJS onError : $code:, $error")
        }

        override fun onProgress(status: Int, info: String?) {
        }
    })
# ·Java
FinAppClient.INSTANCE.getAppletApiManager().callJS(
        "appId",
        "funcName",
        "funParams",
        1,
        new FinCallback<String>() {
            @Override
            public void onSuccess(String result) {
                Log.d(TAG, "callJS onSuccess : " + result);
            }

            @Override
            public void onError(int code, String error) {
                Log.d(TAG, "callJS onError : " + code + ", " + error);
            }

            @Override
            public void onProgress(int status, String info) {

            }
        });

首先,在H5内引用我们的桥接JSSDK (opens new window)文件。

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

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

# 2.3 注册原生组件

# 2.3.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")
    }

}

# 2.3.2 注册原生组件

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

# 2.4 取消注册小程序API

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

# 调用示例

# ·Kotlin
# 单个取消注册
FinAppClient.extensionApiManager.unregisterApi(customApi) 
# 批量取消注册
FinAppClient.extensionApiManager.unregisterApis(apis) 
# ·Java
# 单个取消注册
FinAppClient.INSTANCE.getExtensionApiManager().unregisterApi(customApi); 
# 批量取消注册
FinAppClient.INSTANCE.getExtensionApiManager().unregisterApis(apis); 

# 2.5 取消注册小程序 WebView 组件API

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

# 调用示例
# ·Kotlin
# 单个取消注册
FinAppClient.extensionWebApiManager.unregisterApi(webApi) 
# 批量取消注册
FinAppClient.extensionWebApiManager.unregisterApis(webApis) 
# ·Java
# 单个取消注册
FinAppClient.INSTANCE.getExtensionWebApiManager().unregisterApi(webApi); 
# 批量取消注册
FinAppClient.INSTANCE.getExtensionWebApiManager().unregisterApis(webApis); 

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

# API

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

# 调用示例

# ·Kotlin
val apis = FinAppClient.extensionApiManager.getRegisteredApis() 
# ·Java
Map<String, IApi> apis = FinAppClient.INSTANCE.getExtensionApiManager().getRegisteredApis(); 

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

# API

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

# 调用示例

# ·Kotlin
val apis = FinAppClient.extensionWebApiManager.getRegisteredApis() 
# ·Java
Map<String, IApi> apis = FinAppClient.INSTANCE.getExtensionWebApiManager().getRegisteredApis(); 

# 2.8 在小程序进程中注册api

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

FinAppProcessClient.callback = object : FinAppProcessClient.Callback {
    override fun getRegisterExtensionApis(activity: Activity): List<IApi>? {
        // 在小程序进程中注册小程序扩展API
        return listOf(CustomApi(activity))
    }

    override fun getRegisterExtensionWebApis(activity: Activity): List<IApi>? {
        // 在小程序进程中注册小程序网页调原生API
        return listOf(CustomH5Api(activity))
    }
}

# 2.9 覆盖内置api

默认情况下自定义的api不能覆盖sdk内置的基础api,可通过申请特殊的sdkkey开启覆盖内置api的能力

注意: 覆盖内置api必须在小程序进程注册方可生效

# 3. 扩展SDK

扩展SDK 是对核心SDK的补充,所以要使用扩展SDK,也必须依赖核心SDK。 为了保证 SDK 的安全稳定性,将需要权限的API尽可能放到扩展SDK,FinClip 将 SDK 拆分为核心 SDK 与扩展 SDK,后者是前者的补充,因此使用扩展 SDK 也必须依赖核心 SDK。

获取扩展 SDK

您可登录 资源下载中心 (opens new window) 下载 Android SDK 文件,扩展 SDK 也处于在所下载的压缩包中。

# 3.1 集成扩展SDK

implementation 'com.finogeeks.mop:plugins:+'

# 3.2 小程序API一览

api名称 api描述信息
getLocation 获取位置信息。
getClipboardData 获取剪贴板内容。
setClipboardData 设置剪贴板内容。
recorderManager 全局唯一的录音管理器

# 4. 回调接口

# 4.1 小程序抽象业务回调接口

小程序中部分业务是抽象定义的,这些抽象的业务通过接口的形式暴露给了外部,外部可以自行实现具体的业务逻辑。

所有的抽象业务被定义在IAppletHandler中,应用可以通过调用IAppletApiManagersetAppletHandlerIAppletHandler的实例传给SDK,当业务被触发时,SDK将通过IAppletHandler对应的方法回调给外部,执行外部实现的具体的业务逻辑。

/**
 * 小程序抽象业务回调接口,SDK将这些抽象的业务通过接口的形式暴露给外部,由外部具体实现
 */
interface IAppletHandler {

    interface IAppletCallback {

        /**
         * 成功回调
         */
        fun onSuccess(result: JSONObject? = null)

        /**
         * 失败回调
         */
        fun onFailure()

        /**
         * 取消回调
         */
        fun onCancel()
    }

    /**
     * 转发小程序
     *
     * @param appInfo 小程序信息,是一串json,包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。
     * [appInfo]的内容格式如下:
     * {
     *      "appTitle": "凡泰小程序",
     *      "appAvatar": "https:\/\/www.finogeeks.club\/statics\/images\/swan_mini\/swan_logo.png",
     *      "appId": "5df36b3f687c5c00013e9fd1",
     *      "appType": "trial",
     *      "userId": "finogeeks",
     *      "cryptInfo": "SFODj9IW1ENO8OA0El8P79aMuxB1DJvfKenZd7hrnemVCNcJ+Uj9PzkRkf/Pu5nMz0cGjj0Ne4fcchBRCmJO+As0XFqMrOclsqrXaogsaUPq2jJKCCao03vI8rkHilrWxSDdzopz1ifJCgFC9d6v29m9jU29wTxlHsQUtKsk/wz0BROa+aDGWh0rKvUEPgo8mB+40/zZFNsRZ0PjsQsi7GdLg8p4igKyRYtRgOxUq37wgDU4Ymn/yeXvOv7KrzUT",
     *      "params": {
     *           "title": "apt-test-tweet-接口测试发布的动态!@#¥%……&*(",
     *           "desc": "您身边的服务专家",
     *           "imageUrl": "finfile:\/\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png",
     *           "path": "pages\/tweet\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654",
     *           "appInfo": {
     *               "weixin": {
     *                   "path": "\/studio\/pages\/tweet\/tweet-detail",
     *                   "query": {
     *                       "fcid": "@staff_staff1:000000.finogeeks.com",
     *                       "timelineId": "db0c2098-031e-41c4-b9c6-87a5bbcf681d"
     *                    }
     *               }
     *           }
     *       }
     * }
     * [appInfo]中各字段的说明:
     * appId 小程序ID
     * appTitle 小程序名称
     * appAvatar 小程序头像
     * appType 小程序类型,其中trial表示体验版,temporary表示临时版,review表示审核版,release表示线上版,development表示开发版
     * userId 用户ID
     * cryptInfo 小程序加密信息
     * params 附带的其它参数,由小程序自己透传
     *     
     * @param bitmap 小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址,那么小程序封面图片
     * 就取[appInfo].params.imageUrl对应的图片,否则小程序的封面图片取[bitmap]。
     */
    fun shareAppMessage(appInfo: String, bitmap: Bitmap?, callback: IAppletCallback)

    /**
     * 获取用户信息
     *
     * @return 用户信息[Map]
     */
    fun getUserInfo(): Map<String, String>
  
  	/**
     * 获取用户手机号
     * 通过回调以json格式返回信息,一般格式如下:
     * {"phone": "xxxxxxxxxxx"}
     */
  	override fun getPhoneNumber(callback: IAppletHandler.IAppletCallback) {
        callback.onSuccess(JSONObject().put("phone", "xxxxxxxxxxx"))
    }

  	/**
     * 从小程序页面回到宿主app页面事件,由宿主app实现此操作;
     * @return 如果正确处理该事件返回true,否则返回false.
     */
    override fun launchApp(appParameter: String?): Boolean {
        return false
    }

  	/**
     * 打开"意见反馈"页面,由宿主app接管实现;
     * @return 如果宿主app接管此事件返回true,否则返回false,同时打开默认意见反馈页面。
     */
    override fun feedback(bundle: Bundle): Boolean {
        return false
    }

  	/**
     * 获取用户头像,通过回调返回信息,由SDK透传给小程序
     */
    override fun chooseAvatar(callback: IAppletHandler.IAppletCallback) {
        callback.onFailure()
    }

  	/**
     * 打开客服会话,由宿主app实现具体操作
     * @param json 由小程序透传给宿主app的数据
     * @return 成功打开会话返回true,否则返回false
     */
    override fun contact(json: JSONObject): Boolean {
        return false
    }
    
    /**
     * 获取注册的"更多"菜单项
     *
     * @param appId 小程序ID
     * @return 注册的"更多"菜单项
     */
    fun getRegisteredMoreMenuItems(appId: String): List<MoreMenuItem>?

    /**
     * 注册的"更多"菜单项被点击
     *
     * @param appId 小程序ID
     * @param path 小程序页面路径
     * @param menuItemId 被点击的菜单条目的ID
     * @param appInfo 小程序信息,是一串json,包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。
     * [appInfo]的内容格式如下:
     * {
     *      "appTitle": "凡泰小程序",
     *      "appAvatar": "https:\/\/www.finogeeks.club\/statics\/images\/swan_mini\/swan_logo.png",
     *      "appId": "5df36b3f687c5c00013e9fd1",
     *      "appType": "trial",     
     *      "userId": "finogeeks",
     *      "cryptInfo": "SFODj9IW1ENO8OA0El8P79aMuxB1DJvfKenZd7hrnemVCNcJ+Uj9PzkRkf/Pu5nMz0cGjj0Ne4fcchBRCmJO+As0XFqMrOclsqrXaogsaUPq2jJKCCao03vI8rkHilrWxSDdzopz1ifJCgFC9d6v29m9jU29wTxlHsQUtKsk/wz0BROa+aDGWh0rKvUEPgo8mB+40/zZFNsRZ0PjsQsi7GdLg8p4igKyRYtRgOxUq37wgDU4Ymn/yeXvOv7KrzUT",
     *      "params": {
     *           "title": "apt-test-tweet-接口测试发布的动态!@#¥%……&*(",
     *           "desc": "您身边的服务专家",
     *           "imageUrl": "finfile:\/\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png",
     *           "path": "pages\/tweet\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654",
     *           "appInfo": {
     *               "weixin": {
     *                   "path": "\/studio\/pages\/tweet\/tweet-detail",
     *                   "query": {
     *                       "fcid": "@staff_staff1:000000.finogeeks.com",
     *                       "timelineId": "db0c2098-031e-41c4-b9c6-87a5bbcf681d"
     *                    }
     *               }
     *           }
     *       }
     * }
     * [appInfo]中各字段的说明:
     * appId 小程序ID
     * appTitle 小程序名称
     * appAvatar 小程序头像
     * appType 小程序类型,其中trial表示体验版,temporary表示临时版,review表示审核版,release表示线上版,development表示开发版
     * userId 用户ID
     * cryptInfo 小程序加密信息
     * params 附带的其它参数,由小程序自己透传
     *
     * @param bitmap 小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址,那么小程序封面图片
     * 就取[appInfo].params.imageUrl对应的图片,否则小程序的封面图片取[bitmap]。
     */
    fun onRegisteredMoreMenuItemClicked(appId: String, path: String, menuItemId: String, appInfo: String?, bitmap: Bitmap?, callback: IAppletCallback)
    
    /**
     * 获取灰度发布配置参数
     *
     * @param appId 小程序ID
     * @return 灰度发布配置参数
     */
    fun getGrayAppletVersionConfigs(appId: String): List<GrayAppletVersionConfig>?
    
    /**
     * 小程序导航栏中的"关闭"按钮被点击
     *
     * @param appId 小程序ID
     */
    fun onNavigationBarCloseButtonClicked(appId: String)
}

# 4.2 小程序生命周期回调接口

外部如果需要监听小程序的生命周期,可以调用IAppletApiManagersetAppletLifecycleCallback接口把IAppletLifecycleCallback的实例传给SDK,当小程序的生命周期发生变化时,SDK会通过IAppletLifecycleCallback对应的方法回调给外部。

/**
 * 小程序生命周期回调接口
 */
interface IAppletLifecycleCallback {

    /**
     * 小程序当前页面状态,与[Activity].[onCreate]对应
     */
    fun onCreate(appId: String)

    /**
     * 小程序当前页面状态,与[Activity].[onStart]对应
     */
    fun onStart(appId: String)

    /**
     * 小程序当前页面状态,与[Activity].[onResume]对应
     */
    fun onResume(appId: String)

    /**
     * 小程序当前页面状态,与[Activity].[onPause]对应
     */
    fun onPause(appId: String)

    /**
     * 小程序当前页面状态,与[Activity].[onStop]对应
     */
    fun onStop(appId: String)

    /**
     * 小程序当前页面状态,与[Activity].[onDestroy]对应
     */
    fun onDestroy(appId: String)
}
© 2022 FinClip with ❤

👋🏻 嘿,你好!

「FinClip」是一套基于云原生框架设计的小程序容器。能够让任何移动应用在集成小程序SDK之后,获得可用、安全的小程序运行能力。

>> 点我免费注册体验

查看产品文档
了解与 FinClip 相关的一切信息

产品博客 👈  了解产品更新与核心功能介绍
资源下载 👈  获取小程序 SDK 与开发工具
文档中心 👈  查询 FinClip 小程序开发指南与答疑

商务咨询热线
预约 FinClip 产品介绍,咨询商务报价或私有化部署事宜

400-066-00210755-86967467

获取产品帮助
联系 FinClip 技术顾问,获取产品资料或加入开发者社群

联系线上
人工客服

或 👉  点击这里,提交咨询工单