一、SDK 使用流程介绍
SDK 的使用流程如下:
- SDK 依赖并集成
- SDK 初始化
- 根据业务需求使用相应的功能
二、SDK 集成
SDK 集成需要完成相关依赖库的集成操作。
2.1、集成环境
环境 | 要求 |
---|---|
支持最低SDK版本 | android 5.0系统,SDK_INT>=21 |
kotlin依赖 | 需要 |
2.2、配置依赖库
Android 的 SDK 以 kotlin 语言编写,并尽可能兼容 Java 语言的调用。文档中提及的 flow 为 kotlin 中提供的协程类(如asFlow()
,asFlowOnIO()
等方法),具体的使用请参考 kotlin 官方说明。
2.2.1、配置 maven 仓库
在根项目下的build.gradle
文件中,添加上依赖库相关的 maven 仓库地址。
allprojects {
repositories {
maven { url "https://code.xlink.cn/xlink_open/xlink_maven/-/raw/master" }
}
}
- 如果 maven 仓库配置出现问题无法正常使用,请确认 settings.gradle 中是否有以下的配置,如果存在请移除掉。
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
jcenter() // Warning: this repository is going to shut down soon
}
}
- 如果编译的版本太高可能会导致一些编译时的问题,推荐以下的编译版本
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 21
targetSdkVersion 26
}
}
- 如果出现 gradle 插件异常时,请确认当前的 gradle 版本,目前不支持 7.0 以上的 gradle 插件。
//根项目下的 build.gradle 插件版本
buildscript {
dependencies {
classpath 'com.android.tools.build:gradle:4.0.0'
}
}
//gradle/wrapper/gradle-wrapper.properties配置信息
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
2.2.2、配置依赖文件
在主项目(或需要使用 SDK 的项目)下,在其对应的build.gradle
的文件中,配置以下的依赖库。其中第三方依赖库可以根据需要调整版本号。
注:
- 下述依赖库为默认使用的依赖库及其版本,如果是第三方库/公用库版本与集成的 APP 中的库版本不一致,请自行替换版本并运行。
- SDK 对所有第三方库不强制要求其版本号,只要第三方库的接口及版本兼容处理好均可替换(取决于第三方库的兼容情况)
- 若出现替换版本后确实存在异常情况,请再联系相关对接人员协助处理
//kotlin 官方依赖库
implementation 'org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version'
//网络请求库及其依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation('com.squareup.retrofit2:converter-gson:2.5.0') {
exclude group: 'com.google.code.gson', module: 'gson'
}
implementation 'com.google.code.gson:gson:2.8.6'
implementation 'com.squareup.retrofit2:converter-scalars:2.4.0'
//xlink依赖库
implementation 'cn.xlink:xmaf_core_config:0.1.1-alpha'
如果基于 kotlin 语言开发,并且需要使用 kotlin 的协程功能,则请添加协程依赖库,否则无法使用相关功能。
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0'
如果使用 Java 语言开发,并且使用 RxJava,则请添加 RxJava 相关依赖库,当存在 RxAndroid 的依赖库时,默认将会配置主线程 schedules 确保接口的调用最终在主线程中回调。
implementation "io.reactivex.rxjava2:rxjava:2.2.3"
implementation "io.reactivex.rxjava2:rxandroid:2.1.0"
2.2.3、应用权限要求
仅使用服务功能时,不需要额外的权限,涉及 API 接口请求时(如用户授权服务 XFAuthServer 中的登录操作),请配置网络权限。
<uses-permission android:name="android.permission.INTERNET" />
2.3、SDK 初始化
SDK 集成后需要在使用前初始化。必须确保 SDK 初始化后才能正常使用。初始化 SDK 的部分配置以配置文件的方式提供,需要加载配置文件进行初始化。
在 Android 中不要求 SDK 的初始化必须在 applicatoin 创建时,只需要确保在调用前成功进行了初始化即可。
- 将提供的配置文件(默认文件名为
xlink_config.xf
)置于项目的assets
文件夹中,并以下述的方式读取。
val configInfo = InputStreamReader(assets.open("xlink_config.xf")).readText()
注:放置在其它任何地方都行,只需要以 UTF-8 的编码读取为文本用于加载配置即可。
- 配置并初始化 SDK
//默认的配置初始化,必须使用这个初始化
val config = XFDefaultBuilder()
//添加依赖的服务,如有其它依赖的服务自行添加
//.addServerInitBackground(CustomServer)
.setConfigJson(configInfo)
.build()
XFUnionKit.initConfig(config)
通过以上的操作,初始化操作就完成了。请留意日志中是否有相关的错误信息输出,有的话请参考错误信息说明处理或进行反馈。
2.4、SDK 使用
SDK 的核心为服务,通过提供各种服务来解决业务需求或功能的使用。
tips:服务的介绍说明请参考APP集成说明
三、服务调用
SDK 初始化成功后,即可调用相关的服务,服务调用时统一从 XFServerManager 中获取服务并使用。
3.1、显式调用
服务支持显式调用,显式调用时表示调用者明确知道自己使用的服务类型,并且必须依赖具体的服务类型。一般的显式调用如下:
XFServerManager.getServerAgent<XFAuthServer>("服务ID")
.getServer()
.asFlow()
.onEach{
//明确知道服务是 XFAuthServer 类型,并直接调用其中的方法,同时也必须在编译时依赖该服务
it.addAuthChangedListener(xxx)
}
...
其中 getServer()
的操作会确保服务在使用前初始化,该操作是异步的。
tips:如果需要同步操作可以使用其它同步方法,如
getServerSync()
,但非必要不推荐。
3.2、隐式调用
服务也支持隐式调用,隐式调用时,调用者可以不明确知道自己使用的服务类型,或服务操作,但是必须明确服务调用需要的参数及返回信息。一般的隐式调用如下:
//指定调用的服务ID
XFServerManager.createInvokeBuilder("A")
//指定调用的服务路由
.setRouterPath("B")
//配置服务使用的参数
.withParam("context", context)
//调用服务操作,泛型数据类型是该操作返回的类型,由被调用者定义
.invokeServer<Boolean>()
//转换成异步处理
.asFlowOnIO()
.onEach {
if(it){
Toast.makeText(this, "隐式启动页面成功", Toast.LENGTH_SHORT).show()
}
}
...
- 隐式调用的前提是调用者与被调用者是通过约定的方法进行调用的,如果双方没有约定好或者是不清楚时,可能导致入参错误或出参类型错误,则无法正确完成调用。
在以上示例中,表示:通过调用服务ID为“A”的服务,并使用路由地址为“B”的功能,提供服务需要的参数“context”,调用服务得到返回类型为“Boolean”类型的数据。 - 隐式调用是需要服务本身支持的,如果服务没有实现路由功能的支持与处理,进行隐式调用是肯定会失败的。
- 隐式调用时,返回的参数类型默认是支持可空类型的,在实现时需要留意一下。
tips:如果不太关心出参等信息,出参类型可以用
Any?
承载,但是您必须知道您想要做什么和在做什么,需要与被调用方有约定好的使用方式。
四、异步操作对象
对于服务框架中的接口,绝大部分提供了异步操作接口,同时支持同步操作。异步操作是基于XFAsyncAction
实现的。
方法 | 说明 |
---|---|
execute() | 同步执行操作,会在当前的线程执行操作 |
asFlow() | 转换成 flow 进行处理,注意 flow 是没有指定运行的线程的 |
asFlowOnDispatchers(dispatcher) | 转换成 flow 并指定运行的线程进行处理 |
asFlowOnIO() | 转换成 flow 并运行在 IO 线程 |
asObservable() | 兼容 java 调用方法,转换成 rxjava 的 observable 处理,没有指定运行线程 |
所有的异步操作基于此类,可根据需要进行同步或异步的调用,或者是转换成需要的方式处理。
示例:
XFServerManger.getServerAgent<XFIServer>("server_id")
.getServer()
.asFlowOnIO()
...
4.1、异步操作的错误处理
对于框架中提供的异步操作,当操作中发生异常时将会被抛出,在catch
中可以捕获异常并进行处理。为了方便处理错误,支持将错误类型转换成默认的XFError
错误码类型,从而实现统一的错误码处理。需要明确返回XFError
类型时,请使用相应的扩展方法onXLinkError
。
//此操作中将返回的异常类型固定为 XFError
flow.onXLinkError { ... }
tips:更多错误码信息及说明请参考错误码的相关章节。
4.2、异步操作的转换
由于框架中很多异步操作通过XFAsyncAction
完成,所以可能会出现连续多个操作结果都是XFAsyncAction
并需要依赖上一次操作的结果。对此异步操作对象提供了简单的转换方法,用于将异步操作结果暴露到最终目的行为中。
4.2.1、XFAsyncAction
转换成目标类型
若XFAsyncAction<T>
中的值类型为T
,可以通过以下的方式将结果直接提取出来,并将T
类型转换成任意其它R
类型
val action=XFAsyncAction.create { "" }
//提取出 XFAsyncAction 中的 String,并转换成 Int 类型的数据
.map2X { 0 }
.asFlowOnIO()
...
4.2.2、XFAsyncAction
转换成另一个XFAsyncAction
并提取目标类型
若XFAsyncAction<T>
中的值类型为T
,可以通过以下的方式将结果直接提取出来,并使用T
类型的数据,转换成另一个XFAsyncAction<R>
类型,同时返回R
val action=XFAsyncAction.create { "" }
//提取出 XFAsyncAction 中的 String,并转换成另一个 XFAsyncAction 对象
.map2AsyncX { XFAsyncAction.create { 0 } }
.map2X { it.toString() }
.asFlowOnIO()
...
此方法在对服务调用时非常便捷。
XFServerManager.getServerAgent<XFAuthServer>(XFAuthServer.SERVER_ID)
.getServer()
//获取的是一个异步操作对象 XFAsyncAction<XFAuthServer>
.map2AsyncX { it.authAccount(AuthParams("企业ID", "账号", "密码", false)) }
.asFlowOnIO()
...
五、更新说明
日期 | 版本 | 更新内容 |
---|---|---|
2021-12-24 | v2.3 | 更新文档信息 |
2021-10-29 | v2.2 | 更新部分文档说明 |
2021-10-22 | v2.0 | 优化服务调用方式 |
2021-10-15 | v1.0 | 集成文档 |