UI 库 ChatKit 使用指南
ChatKit 是一个免费且开源的 UI 聊天组件,由 LeanCloud 官方推出,底层聊天服务基于 LeanCloud 的 IM 即时通讯服务 LeanMessage 而开发。它的最大特点是把聊天常用的一些功能配合 UI 一起提供给开发者,帮助开发者快速集成 IM 服务,轻松实现聊天功能。
ChatKit 开源且提供完全自由的授权协议,开发者可以对其进行任意修改、扩展和二次封装,但是 LeanCloud 并不对 ChatKit 的二次开发提供技术支持。
获取项目
git clone git@github.com:leancloud/LeanCloudChatKit-Android.git
运行 Demo
获取源代码之后,用 Android Studio 打开项目,左侧的 Project 视图显示为:
「ChatKit-Android」Project 包含两个模块:
- leancloudchatkit
是一个封装了 LeanCloud 即时通讯的 UI lib,其目的是让开发者更快速地接入 LeanCloud 即时通讯的功能。 - chatkitapplication
为 Demo 项目,它是一个简单的示例项目,用来指导开发者如何使用 leancloudchatkit。
然后,请确保电脑上已经连接了一台真机或者虚拟机用作调试。
点击 Debug 或者 Run,第一次启动会运行 Gradle Build。建议打开全局网络代理,否则 Gradle Build 可能会因为网络原因无法完成。
使用方法
开发者可以将 ChatKit 导入到自己的 Project 中使用。下面我们将新建一个 Project(名为 ChatDemo) 用以导入 ChatKit。导入方式推荐通过源代码导入。
源代码导入
- 浏览器访问 https://github.com/leancloud/LeanCloudChatKit-Android;
- 执行以下命令行,将项目 clone 到本地(如
ChatKit
文件夹中,或者直接下载 zip 包自行解压缩到此文件夹下):
git clone https://github.com/leancloud/LeanCloudChatKit-Android.git`
- 将文件夹
leancloudchatkit
复制到ChatDemo
根目录; - 修改
ChatDemo/settings.gradle
加入include ':leancloudchatkit'
; - 修改
ChatDemo/app/build.gradle
,在 dependencies 中添加compile project(":leancloudchatkit")
。
最后只要 Sync Project,这样 ChatKit 就算是导入到项目中了。
自定义使用
一、实现自己的 Application
ChatKit 在使用之前需要进行初始化,就像直接使用 LeanCloud 基础 SDK 时需要调用 AVOSCloud.initialize(appId, appKey)
一样。初始化逻辑应该放在 Application.onCreate
方法中实现。
ChatDemo 中新建一个 Class,名字叫做 ChatDemoApplication,让它继承自 Application 类,代码如下:
public class ChatDemoApplication extends Application {
// appId、appKey 可以在「LeanCloud 控制台 > 设置 > 应用凭证」获取
private final String APP_ID = "********";
private final String APP_KEY = "********";
@Override
public void onCreate() {
super.onCreate();
// 关于 CustomUserProvider 可以参看后面的文档
LCChatKit.getInstance().setProfileProvider(CustomUserProvider.getInstance());
LCChatKit.getInstance().init(getApplicationContext(), APP_ID, APP_KEY);
}
}
二、在 AndroidMainfest.xml
中配置 ChatDemoApplication
<application
...
android:name=".ChatDemoApplication" >
...
</application>
三、实现自己的用户体系
一般来说,聊天界面要相对复杂一些,不但要支持文字、表情、图片、语音等消息格式,还要展示用户信息,比如用户的头像、昵称等。而 LeanCloud 的消息流中只包含用户的 clientId
这一唯一标识,所以要获取头像这类额外的用户信息,就需要开发者接入自己的用户系统来实现。
为了保证通用性和扩展性,让开发者可以更容易将聊天界面嵌入自己的应用中,ChatKit 在设计上抽象出了一个「用户体系」的接口,需要开发者自己提供用户信息的获取方式。该接口只有一个方法需要开发者实现:
/**
* 用户体系的接口,开发者需要实现此接口来接入 LCChatKit
*/
public interface LCChatProfileProvider {
// 根据传入的 clientId list,查找、返回用户的 Profile 信息(id、昵称、头像)
public void fetchProfiles(List<String> userIdList, LCChatProfilesCallBack profilesCallBack);
}
为此,我们在 ChatDemo 中新建一个 Class,名字叫做 CustomUserProvider,代码如下:
public class CustomUserProvider implements LCChatProfileProvider {
private static CustomUserProvider customUserProvider;
public synchronized static CustomUserProvider getInstance() {
if (null == customUserProvider) {
customUserProvider = new CustomUserProvider();
}
return customUserProvider;
}
private CustomUserProvider() {
}
private static List<LCChatKitUser> partUsers = new ArrayList<LCChatKitUser>();
// 此数据均为模拟数据,仅供参考
static {
partUsers.add(new LCChatKitUser("Tom", "Tom", "http://www.avatarsdb.com/avatars/tom_and_jerry2.jpg"));
partUsers.add(new LCChatKitUser("Jerry", "Jerry", "http://www.avatarsdb.com/avatars/jerry.jpg"));
partUsers.add(new LCChatKitUser("Harry", "Harry", "http://www.avatarsdb.com/avatars/young_harry.jpg"));
partUsers.add(new LCChatKitUser("William", "William", "http://www.avatarsdb.com/avatars/william_shakespeare.jpg"));
partUsers.add(new LCChatKitUser("Bob", "Bob", "http://www.avatarsdb.com/avatars/bath_bob.jpg"));
}
@Override
public void fetchProfiles(List<String> list, LCChatProfilesCallBack callBack) {
List<LCChatKitUser> userList = new ArrayList<LCChatKitUser>();
for (String userId : list) {
for (LCChatKitUser user : partUsers) {
if (user.getUserId().equals(userId)) {
userList.add(user);
break;
}
}
}
callBack.done(userList, null);
}
public List<LCChatKitUser> getAllUsers() {
return partUsers;
}
}
当用户昵称和头像需要更新时,需要覆盖旧的 LCChatKitUser
对象并更新本地缓存:
LCChatKitUser user = new LCChatKitUser("唯一 userId 不可变", "要变更的昵称", "要变更的 avatarURL");
LCIMProfileCache.getInstance().cacheUser(user);
四、打开即时通讯,并且跳转到聊天页面
我们支持通过两种方式来打开聊天界面:
- 通过指定另一个参与者的 clientId 的方式,开启一对一的聊天;
此时,通过调用intent.putExtra(LCIMConstants.PEER_ID, "peermemberId")
来传递另一参与者的 clientId。 - 通过指定一个已经存在的 LCIMConversation id 的方式,开启单人、多人或者开放式聊天室;
此时,通过调用LCIMConstants.CONVERSATION_ID, "particularConversationId")
来传递特定对话 Id。
下面的代码展示了如何通过第一种方式来开启聊天界面:
LCChatKit.getInstance().open("Tom", new AVIMClientCallback() {
@Override
public void done(AVIMClient avimClient, AVIMException e) {
if (null == e) {
finish();
Intent intent = new Intent(MainActivity.this, LCIMConversationActivity.class);
intent.putExtra(LCIMConstants.PEER_ID, "Jerry");
startActivity(intent);
} else {
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
}
}
});
这样,Tom 就可以和 Jerry 愉快地聊天了。
接口以及组件
以下介绍在 ChatKit 中开发者常需要关注的业务逻辑组件(Interface)和界面组件(UI)。
用户
LCChatKitUser
是 ChatKit 封装的参与聊天的用户,它提供了如下属性:
名称 | 描述 |
---|---|
userId | 用户在单个应用内唯一的 ID,也是调用 LCChatKit.open 时传入的 userId。 |
avatarUrl | 用户头像的 URL |
name | 用户名 |
使用这些默认的属性基本可以满足一个聊天应用的需求,同时开发者可以通过继承 LCChatKitUser
类实现更多属性。具体用法请参考 Demo 中的 MembersAdapter.java
。
用户信息管理类
LCChatProfileProvider
接口需要用户 implements 后实现 fetchProfiles
函数,以使 ChatKit 在需要显示的时候展示用户相关的信息。
例如 Demo 中的 CustomUserProvider
这个类,它实现了 LCChatProfileProvider
接口,在 fetchProfiles
方法里加载了 Tom、Jerry 等人的信息。
核心类
LCChatKit
是 ChatKit 的核心类,具体逻辑可以参看代码,注意以下几个主要函数:
- `public void init(Context context, String appId, String appKey)`
- 此函数用于初始化 ChatKit 的相关设置,此函数要在 Application 的 `onCreate` 中调用,否则可能会引起异常。
- `public void setProfileProvider(LCChatProfileProvider profileProvider)`
- 此函数用于设置用户体系,因为 LeanCloud 即时通讯功能已经实现了完全剥离用户体系的功能,这里接入已有的用户体系会很方便。
- `public void open(final String userId, final AVIMClientCallback callback)`
- 此函数用于开始即时通讯,open 成功后可以执行自己的逻辑,或者跳转到聊天页面。
对话列表界面
对话 LCIMConversation
是 LeanMessage 封装的用来管理对话中的成员以及发送消息的载体,不论是群聊还是单聊都是在一个对话当中;而对话列表可以作为聊天应用默认的首页显示出来,主流的社交聊天软件,例如微信,就是把最近的对话列表作为登录后的首页。
因此,我们也提供了对话列表 LCIMConversationListFragment
页面供开发者使用,在 Demo 项目中的 MainActivity
中的 initTabLayout
方法中演示了如何引入对话列表页面:
private void initTabLayout() {
String[] tabList = new String[]{"会话", "联系人"};
final Fragment[] fragmentList = new Fragment[] {new LCIMConversationListFragment(),
new ContactFragment()};
// 以上这段代码为新建了一个 Fragment 数组,并且把 LCIMConversationListFragment 作为默认显示的第一个 Tab 页面
tabLayout.setTabMode(TabLayout.MODE_FIXED);
for (int i = 0; i < tabList.length; i++) {
tabLayout.addTab(tabLayout.newTab().setText(tabList[i]));
}
...
}
具体的显示效果如下:
聊天界面
聊天界面是显示频率最高的前端页面,ChatKit 通过 LCIMConversationFragment
和 LCIMConversationActivity
来实现这一界面。在 Demo 的 ContactItemHolder
界面包含了使用 LCIMConversationActivity
的实例:
public void initView() {
nameView = (TextView)itemView.findViewById(R.id.tv_friend_name);
avatarView = (ImageView)itemView.findViewById(R.id.img_friend_avatar);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 点击联系人,直接跳转进入聊天界面
Intent intent = new Intent(getContext(), LCIMConversationActivity.class);
// 传入对方的 Id 即可
intent.putExtra(LCIMConstants.PEER_ID, lcChatKitUser.getUserId());
getContext().startActivity(intent);
}
});
}
具体的显示效果如下:
联系人列表页面
因为 ChatKit 是与应用的用户体系完全解耦的,所以 ChatKit 中并没有包含联系人列表页面,但部分开发者可能有此需求,所以 chatkitapplication 实现了一个基于 LCChatProfileProvider 的联系人列表页面,具体代码可以参考 ContactFragment.java, 具体效果如下:
常见问题
ChatKit 组件收费么?
ChatKit 是完全开源并且免费给开发者使用,使用聊天所产生的费用以账单为准。
接入 ChatKit 有什么好处?
它可以减轻应用或者新功能研发初期的调研成本,直接引入使用即可。ChatKit 从底层到 UI 提供了一整套的聊天解决方案。