我们于 2018 年 9 月推出了新的 Java Unified SDK(以下简称为「Java SDK」),兼容纯 Java、云引擎和 Android 等多个平台,老的 Android SDK(版本号低于 5.0.0,groupId 为 cn.leancloud.android 的 libraries)于 2019 年 9 月底停止维护。欢迎老 SDK 的用户尽快切换到新的 Java SDK,具体迁移方法详见 Java Unified SDK 迁移指南。
5.0.0
groupId
cn.leancloud.android
Java Unified SDK 根据底层依赖的 JSON 解析库的不同,有两个不同分支:
两个版本的对外接口完全一致,开发者可以根据自己的需求选择合适的版本。但是考虑到平台兼容性和稳定性,我们推荐大家使用 7.x 的分支来进行开发。下面的流程都是基于 7.x 版本的 SDK 书写的,切换到 7.x 的改动非常小,原来使用 6.x 版本的开发者可以参考Java Unified SDK 迁移指南中「从 6.x 迁移到 7.x 版本的操作要点」一节的说明进行升级。
Java SDK 主要包含以下几个 library,其层次结构以及平台对应关系如下:
Java SDK 一共包含如下几个模块:
获取 SDK 有多种方式,较为推荐的方式是通过包依赖管理工具下载最新版本。
我们已经将所有的 library 发布到了 maven 中心仓库,开发者可以用以下任意包管理工具来安装 SDK。
Maven:
<dependency> <groupId>cn.leancloud</groupId> <artifactId>storage-core</artifactId> <version>7.2.2</version> </dependency>
Ivy:
<dependency org="cn.leancloud" name="storage-core" rev="7.2.2" />
SBT:
libraryDependencies += "cn.leancloud" %% "storage-core" % "7.2.2"
Gradle:
implementation 'cn.leancloud:storage-core:7.2.2'
如果是 Android 项目,则换成以下这些包:
implementation 'cn.leancloud:storage-android:7.2.2' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Example for Maven:
<dependency> <groupId>cn.leancloud</groupId> <artifactId>realtime-core</artifactId> <version>7.2.2</version> </dependency>
and for Ivy:
<dependency org="cn.leancloud" name="realtime-core" rev="7.2.2" />
and for SBT:
libraryDependencies += "cn.leancloud" %% "realtime-core" % "7.2.2"
and for Gradle:
implementation 'cn.leancloud:realtime-android:7.2.2' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Example for Gradle:
implementation 'cn.leancloud:mixpush-android:7.2.2' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
请注意,这里的讨论仅针对 6.x 版本的 SDK 有效。
从 6.5.0 版本开始,我们 Java 平台和 Android 平台的 SDK 都统一依赖 fastjson 最新的 JVM 版本(1.2.68),开发者在使用的时候不需要做特殊的处理。
6.5.0
1.2.68
对 6.5.0 之前的 SDK 版本,我们根据使用环境做了不同的依赖选择: storage-core 依赖的是面向纯 Java 平台的 fastjson(版本为 1.2.60); storage-android 和 realtime-android 以及其他推送 sdk 依赖的是面向 Android 平台的 fastjson(版本为 1.1.71.android)。 同时,我们发现 Android 版本的 fastjson 库在反序列化的时候,对 double 和 float 类型的处理存在漏洞。如果属性值中存在 3.1415F 或 3.1415D 这样的数字,JSON#parse 方法会抛出异常,异常信息类似于 com.alibaba.fastjson.JSONException: syntax error, pos 123, json : xxx。为此我们提供了一个临时的 bugfix 版本供开发者下载使用,下载地址见这里。开发者可以通过引用本地文件的方式来依赖这个版本,build.gradle 中的依赖部分可按照如下示例进行更改:
对 6.5.0 之前的 SDK 版本,我们根据使用环境做了不同的依赖选择:
1.2.60
1.1.71.android
同时,我们发现 Android 版本的 fastjson 库在反序列化的时候,对 double 和 float 类型的处理存在漏洞。如果属性值中存在 3.1415F 或 3.1415D 这样的数字,JSON#parse 方法会抛出异常,异常信息类似于 com.alibaba.fastjson.JSONException: syntax error, pos 123, json : xxx。为此我们提供了一个临时的 bugfix 版本供开发者下载使用,下载地址见这里。开发者可以通过引用本地文件的方式来依赖这个版本,build.gradle 中的依赖部分可按照如下示例进行更改:
3.1415F
3.1415D
com.alibaba.fastjson.JSONException: syntax error, pos 123, json : xxx
implementation fileTree(include: ['*.jar'], dir: 'libs') // 注意把上面的 lib 拷贝到该目录下 implementation('cn.leancloud:realtime-android:6.4.4') { // 注意替换具体的版本号 exclude group: 'com.alibaba', module: 'fastjson' exclude group: 'org.ligboy.retrofit2', module: 'converter-fastjson' } implementation('cn.leancloud:storage-android:6.4.4') { // 注意替换具体的版本号 exclude group: 'com.alibaba', module: 'fastjson' exclude group: 'org.ligboy.retrofit2', module: 'converter-fastjson' } // implementation 'com.alibaba:fastjson:1.1.71.android' // 注意删除这一行 implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation("org.ligboy.retrofit2:converter-fastjson-android:2.1.0") { exclude group: 'com.alibaba', module: 'fastjson' // 注意增加这一行 }
我们发现有时候 Maven 源的 CDN 缓存同步策略出现问题,可能会导致我们某个版本或者该版本下某种格式的 library 文件无法下载,这时候你可以在配置文件中显式增加一个 Sonatype 的源,就可以解决找不到文件的问题。
Maven pom.xml 的修改示例如下:
<repositories> <repository> <id>oss-sonatype</id> <name>oss-sonatype</name> <url>https://oss.sonatype.org/content/groups/public/</url> </repository> </repositories>
Gradle build.gradle 的修改示例如下:
buildscript { repositories { google() jcenter() // 增加下面的配置 maven { url "https://oss.sonatype.org/content/groups/public/" } } } allprojects { repositories { google() jcenter() // 增加下面的配置 maven { url "https://oss.sonatype.org/content/groups/public/" } } }
下载 SDK
可以执行以下命令获取 Java SDK 并安装:
$ git clone https://github.com/leancloud/java-unified-sdk.git $ cd java-unified-sdk/ $ mvn clean install
获取和安装 Android SDK:
$ cd java-unified-sdk/ $ cd android-sdk/ $ gradle clean assemble
首先进入 控制台 > 设置 > 应用 Key 来获取 App ID,App Key 以及服务器地址。
如果是一个 Android 项目,则向 Application 类的 onCreate 方法添加:
Application
onCreate
import cn.leancloud.AVOSCloud; public class MyLeanCloudApp extends Application { @Override public void onCreate() { super.onCreate(); // 提供 this、App ID、App Key、Server Host 作为参数 // 注意这里千万不要调用 cn.leancloud.core.AVOSCloud 的 initialize 方法,否则会出现 NetworkOnMainThread 等错误。 AVOSCloud.initialize(this, "{{appid}}", "{{appkey}}", "https://please-replace-with-your-customized.domain.com"); } }
请将 https://please-replace-with-your-customized.domain.com 替换为你的应用绑定的 API 域名。
https://please-replace-with-your-customized.domain.com
国际版应用不要求绑定自定义域名。 如果你的国际版应用(App ID 后缀为 -MdYXbMMI)没有绑定自定义域名,初始化 SDK 时不用传入服务器地址参数。 极个别 App ID 后缀不为 -MdYXbMMI 的国际版应用,请参见这里的说明。
-MdYXbMMI
然后指定 SDK 需要的权限并在 AndroidManifest.xml 里面声明 MyLeanCloudApp 类:
AndroidManifest.xml
MyLeanCloudApp
<!-- 基本模块(必须)START --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 基本模块 END --> <application … android:name=".MyLeanCloudApp" > <!-- 即时通讯和推送 START --> <!-- 即时通讯和推送都需要 PushService --> <service android:name="cn.leancloud.push.PushService"/> <receiver android:name="cn.leancloud.push.AVBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.USER_PRESENT"/> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> <!-- 即时通讯和推送 END --> </application>
注意:对于只使用 LeanCloud 即时通讯服务,而不使用推送服务的应用来说,在初始化的时候设置 AVIMOptions#disableAutoLogin4Push 选项,可以加快即时通讯用户登录的过程。设置方法如下: // 在 AVOSCloud#initialize 之后调用,禁止自动发送推送服务的 login 请求。 AVIMOptions.getGlobalOptions().setDisableAutoLogin4Push(true);
注意:对于只使用 LeanCloud 即时通讯服务,而不使用推送服务的应用来说,在初始化的时候设置 AVIMOptions#disableAutoLogin4Push 选项,可以加快即时通讯用户登录的过程。设置方法如下:
// 在 AVOSCloud#initialize 之后调用,禁止自动发送推送服务的 login 请求。 AVIMOptions.getGlobalOptions().setDisableAutoLogin4Push(true);
对 Android 开发者来说,从 6.1.0 版本开始,除了支持通过 appId + appKey 完成初始化,我们还提供一种更加安全的使用方式,支持仅仅通过 appId 来初始化应用,例如:
import cn.leancloud.AVOSCloud; public class MyLeanCloudApp extends Application { @Override public void onCreate() { super.onCreate(); // 提供 this、App ID、绑定的自定义 API 域名作为参数 AVOSCloud.initializeSecurely(this, "{{appid}}", "https://please-replace-with-your-customized.domain.com"); } }
这时候程序初始化不再需要 appKey,避免了核心配置信息在客户端泄漏可能带来的潜在风险。具体的集成方法可参看文档 Android SDK 更安全的接入和初始化方式。
如果是一个普通 Java 项目,则在代码开头添加:
import cn.leancloud.core.AVOSCloud; AVOSCloud.initialize("{{appid}}", "{{appkey}}", "https://please-replace-with-your-customized.domain.com");
注意,云引擎内部访问 API 是通过内网,所以不需要也不应该配置 API 自定义域名(serverUrl)。 模板项目和云引擎网站托管开发指南中的示例代码均未配置 API 自定义域名, 请勿调用 setServer,否则会变成公网访问,影响性能。
serverUrl
setServer
LeanCloud realtime-core library 也支持在纯 Java Application 中使用,但是与 Android 的调用方式有细微差异,Java Application 中需要开发者显式建立与 LeanCloud 即时通讯云端的长链接(Android 平台是通过 PushService 自动建立的)。建立长链接的方法如下:
AVConnectionManager.getInstance().startConnection(new AVCallback() { @Override protected void internalDone0(Object o, AVException e) { if (e == null) { System.out.println("成功建立 WebSocket 链接"); } else { System.out.println("建立 WebSocket 链接失败:" + e.getMessage()); } } });
只有长链接成功建立之后,后续的聊天请求才能开始。
在应用开发阶段,你可以选择开启 SDK 的调试日志(debug log)来方便追踪问题。调试日志开启后,SDK 会把网络请求、错误消息等信息输出到 IDE 的日志窗口,或是浏览器 Console 或是 LeanCloud 控制台的云引擎日志中。
// 在 AVOSCloud.initialize() 之前调用 AVOSCloud.setLogLevel(AVLogger.Level.DEBUG);
详细调试流程可以参考Android SDK 调试指南。
在应用发布之前,请关闭调试日志,以免暴露敏感数据。
首先,确认本地网络环境是可以访问 LeanCloud 服务器的,可以执行以下命令:
curl "https://API_BASE_URL/1.1/date"
API_BASE_URL 为绑定的 API 自定义域名。
API_BASE_URL
如果当前网路正常会返回当前时间:
{"__type":"Date","iso":"2020-10-12T06:46:56.000Z"}
然后在项目中编写如下测试代码:
AVObject testObject = new AVObject("TestObject"); testObject.put("words", "Hello world!"); testObject.saveInBackground().blockingSubscribe();
保存后运行程序。
然后打开 控制台 > 存储 > 数据 > TestObject,如果看到如下内容,说明 SDK 已经正确地执行了上述代码,安装完毕。
TestObject
如果控制台没有发现对应的数据,请参考 问题排查。
SDK 安装指南基于当前最新版本的 SDK 编写,所以排查问题前,请先检查下安装的 SDK 是不是最新版本。
401 Unauthorized
如果 SDK 抛出 401 异常或者查看本地网络访问日志存在:
401
{ "code": 401, "error": "Unauthorized." }
则可认定为 App ID 或者 App Key 输入有误,或者是不匹配,很多开发者同时注册了多个应用,导致拷贝粘贴的时候,用 A 应用的 App ID 匹配 B 应用的 App Key,这样就会出现服务端鉴权失败的错误。
客户端尤其是手机端,应用在访问网络的时候需要申请一定的权限。
Android / Java SDK 安装指南
SDK 维护期说明
我们于 2018 年 9 月推出了新的 Java Unified SDK(以下简称为「Java SDK」),兼容纯 Java、云引擎和 Android 等多个平台,老的 Android SDK(版本号低于
5.0.0
,groupId
为cn.leancloud.android
的 libraries)于 2019 年 9 月底停止维护。欢迎老 SDK 的用户尽快切换到新的 Java SDK,具体迁移方法详见 Java Unified SDK 迁移指南。Java Unified SDK 根据底层依赖的 JSON 解析库的不同,有两个不同分支:
两个版本的对外接口完全一致,开发者可以根据自己的需求选择合适的版本。但是考虑到平台兼容性和稳定性,我们推荐大家使用 7.x 的分支来进行开发。下面的流程都是基于 7.x 版本的 SDK 书写的,切换到 7.x 的改动非常小,原来使用 6.x 版本的开发者可以参考Java Unified SDK 迁移指南中「从 6.x 迁移到 7.x 版本的操作要点」一节的说明进行升级。
平台与 SDK 对应关系
Java SDK 主要包含以下几个 library,其层次结构以及平台对应关系如下:
基础包(可以在纯 Java 环境下调用)
Android 特有的包
模块依赖关系
Java SDK 一共包含如下几个模块:
获取 SDK
获取 SDK 有多种方式,较为推荐的方式是通过包依赖管理工具下载最新版本。
包依赖管理工具安装
我们已经将所有的 library 发布到了 maven 中心仓库,开发者可以用以下任意包管理工具来安装 SDK。
使用存储功能
Maven:
Ivy:
SBT:
Gradle:
如果是 Android 项目,则换成以下这些包:
使用即时通讯 / 推送服务
Example for Maven:
and for Ivy:
and for SBT:
and for Gradle:
使用混合推送服务
Example for Gradle:
对 fastjson 的特别说明
请注意,这里的讨论仅针对 6.x 版本的 SDK 有效。
从
6.5.0
版本开始,我们 Java 平台和 Android 平台的 SDK 都统一依赖 fastjson 最新的 JVM 版本(1.2.68
),开发者在使用的时候不需要做特殊的处理。对 maven 源的特别说明
我们发现有时候 Maven 源的 CDN 缓存同步策略出现问题,可能会导致我们某个版本或者该版本下某种格式的 library 文件无法下载,这时候你可以在配置文件中显式增加一个 Sonatype 的源,就可以解决找不到文件的问题。
Maven pom.xml 的修改示例如下:
Gradle build.gradle 的修改示例如下:
手动安装
下载 SDK
从源码编译
可以执行以下命令获取 Java SDK 并安装:
获取和安装 Android SDK:
初始化
首先进入 控制台 > 设置 > 应用 Key 来获取 App ID,App Key 以及服务器地址。
Android 平台初始化
如果是一个 Android 项目,则向
Application
类的onCreate
方法添加:请将
https://please-replace-with-your-customized.domain.com
替换为你的应用绑定的 API 域名。国际版应用不要求绑定自定义域名。 如果你的国际版应用(App ID 后缀为
-MdYXbMMI
)没有绑定自定义域名,初始化 SDK 时不用传入服务器地址参数。 极个别 App ID 后缀不为-MdYXbMMI
的国际版应用,请参见这里的说明。然后指定 SDK 需要的权限并在
AndroidManifest.xml
里面声明MyLeanCloudApp
类:更安全的客户端初始化方法
对 Android 开发者来说,从 6.1.0 版本开始,除了支持通过 appId + appKey 完成初始化,我们还提供一种更加安全的使用方式,支持仅仅通过 appId 来初始化应用,例如:
这时候程序初始化不再需要 appKey,避免了核心配置信息在客户端泄漏可能带来的潜在风险。具体的集成方法可参看文档 Android SDK 更安全的接入和初始化方式。
Java 平台初始化代码
如果是一个普通 Java 项目,则在代码开头添加:
注意,云引擎内部访问 API 是通过内网,所以不需要也不应该配置 API 自定义域名(
serverUrl
)。 模板项目和云引擎网站托管开发指南中的示例代码均未配置 API 自定义域名, 请勿调用setServer
,否则会变成公网访问,影响性能。LeanCloud realtime-core library 也支持在纯 Java Application 中使用,但是与 Android 的调用方式有细微差异,Java Application 中需要开发者显式建立与 LeanCloud 即时通讯云端的长链接(Android 平台是通过 PushService 自动建立的)。建立长链接的方法如下:
只有长链接成功建立之后,后续的聊天请求才能开始。
开启调试日志
在应用开发阶段,你可以选择开启 SDK 的调试日志(debug log)来方便追踪问题。调试日志开启后,SDK 会把网络请求、错误消息等信息输出到 IDE 的日志窗口,或是浏览器 Console 或是 LeanCloud 控制台的云引擎日志中。
详细调试流程可以参考Android SDK 调试指南。
在应用发布之前,请关闭调试日志,以免暴露敏感数据。
验证
首先,确认本地网络环境是可以访问 LeanCloud 服务器的,可以执行以下命令:
API_BASE_URL
为绑定的 API 自定义域名。如果当前网路正常会返回当前时间:
然后在项目中编写如下测试代码:
保存后运行程序。
然后打开 控制台 > 存储 > 数据 >
TestObject
,如果看到如下内容,说明 SDK 已经正确地执行了上述代码,安装完毕。如果控制台没有发现对应的数据,请参考 问题排查。
问题排查
SDK 安装指南基于当前最新版本的 SDK 编写,所以排查问题前,请先检查下安装的 SDK 是不是最新版本。
401 Unauthorized
如果 SDK 抛出
401
异常或者查看本地网络访问日志存在:则可认定为 App ID 或者 App Key 输入有误,或者是不匹配,很多开发者同时注册了多个应用,导致拷贝粘贴的时候,用 A 应用的 App ID 匹配 B 应用的 App Key,这样就会出现服务端鉴权失败的错误。
客户端无法访问网络
客户端尤其是手机端,应用在访问网络的时候需要申请一定的权限。