html5中文学习网

您的位置: 首页 > android » 正文

Android 应用APP加入聊天功能_Android

[ ] 已经帮助:人解决问题

简介6LkHTML5中文学习网 - HTML5先行者学习网

自去年 LeanCloud 发布实时通信(IM)服务之后,基于用户反馈和工程师对需求的消化和对业务的提炼,上周正式发布了「实时通信 2.0 」。设计理念依然是「灵活、解耦、可组合、可定制」,具体可以参考《实时通信开发指南》,了解 LeanCloud 实时通信的基本概念和模型。6LkHTML5中文学习网 - HTML5先行者学习网

下载和安装6LkHTML5中文学习网 - HTML5先行者学习网

可以到 LeanCloud 官方下载点下载 LeanCloud IM SDK v2 版本。将下载到的 jar 包加入工程即可。6LkHTML5中文学习网 - HTML5先行者学习网

一对一的文本聊天6LkHTML5中文学习网 - HTML5先行者学习网

我们先从最简单的环节入手,看看怎么用 LeanCloud IM SDK v2 实现一对一文本聊天。6LkHTML5中文学习网 - HTML5先行者学习网

初始化6LkHTML5中文学习网 - HTML5先行者学习网

和 LeanCloud 其他服务一样,实时聊天服务的初始化也是在 Application 的 onCreate 方法中进行的:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class MyApplication extends Application{6LkHTML5中文学习网 - HTML5先行者学习网
    public void onCreate(){6LkHTML5中文学习网 - HTML5先行者学习网
      ...6LkHTML5中文学习网 - HTML5先行者学习网
      AVOSCloud.initialize(this,"{{appId}}","{{appKey}}");6LkHTML5中文学习网 - HTML5先行者学习网
      ...6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

并且在AndroidManifest.xml中间声明:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
<manifest>6LkHTML5中文学习网 - HTML5先行者学习网
   ...6LkHTML5中文学习网 - HTML5先行者学习网
   <application6LkHTML5中文学习网 - HTML5先行者学习网
        android:name=".MyApplication"6LkHTML5中文学习网 - HTML5先行者学习网
        ....>6LkHTML5中文学习网 - HTML5先行者学习网
        ...6LkHTML5中文学习网 - HTML5先行者学习网
        <service android:name="com.avos.avoscloud.PushService" />6LkHTML5中文学习网 - HTML5先行者学习网
        <receiver android:name="com.avos.avoscloud.AVBroadcastReceiver">6LkHTML5中文学习网 - HTML5先行者学习网
            <intent-filter>6LkHTML5中文学习网 - HTML5先行者学习网
                <action android:name="android.intent.action.BOOT_COMPLETED" />6LkHTML5中文学习网 - HTML5先行者学习网
                <action android:name="android.intent.action.USER_PRESENT" />6LkHTML5中文学习网 - HTML5先行者学习网
            </intent-filter>6LkHTML5中文学习网 - HTML5先行者学习网
        </receiver>6LkHTML5中文学习网 - HTML5先行者学习网
        ...6LkHTML5中文学习网 - HTML5先行者学习网
   </application>6LkHTML5中文学习网 - HTML5先行者学习网
</manifest>6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

接下来我们需要完成用户登录。6LkHTML5中文学习网 - HTML5先行者学习网

登录6LkHTML5中文学习网 - HTML5先行者学习网

假定聊天发起方名叫 Tom,为直观起见,我们使用用户名来作为 clientId 登录聊天系统(LeanCloud 云端只要求 clientId 在应用内唯一即可,具体用什么数据由应用层决定),代码如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
AVIMClient imClient = AVIMClient.getInstance("Tom");6LkHTML5中文学习网 - HTML5先行者学习网
imClient.open(new IMClientCallback(){6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVIMClient client, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (e) {6LkHTML5中文学习网 - HTML5先行者学习网
        // 出错了,可能是网络问题无法连接 LeanCloud 云端,请检查网络之后重试。6LkHTML5中文学习网 - HTML5先行者学习网
        // 此时聊天服务不可用。6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
        // 成功登录,可以开始进行聊天了。6LkHTML5中文学习网 - HTML5先行者学习网
    };6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

建立对话6LkHTML5中文学习网 - HTML5先行者学习网

假定我们要跟「Bob」这个用户进行聊天,我们先创建一个对话,代码如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
// 下面的代码包含了实际应用中的所有逻辑:查询->创建「对话」。6LkHTML5中文学习网 - HTML5先行者学习网
// 先查询一下是否已经存在与「Bob」的私聊对话,可以先忽略这部分代码6LkHTML5中文学习网 - HTML5先行者学习网
List<String> clientIds = new ArrayList<String>();6LkHTML5中文学习网 - HTML5先行者学习网
clientIds.add("Tom");6LkHTML5中文学习网 - HTML5先行者学习网
clientIds.add("Bob");6LkHTML5中文学习网 - HTML5先行者学习网
AVIMConversationQuery conversationQuery = imClient.getQuery();6LkHTML5中文学习网 - HTML5先行者学习网
conversationQuery.withMembers(clientIds);6LkHTML5中文学习网 - HTML5先行者学习网
// 之前有常量定义:6LkHTML5中文学习网 - HTML5先行者学习网
// int ConversationType_OneOne = 0; // 两个人之间的单聊6LkHTML5中文学习网 - HTML5先行者学习网
// int ConversationType_Group = 1;  // 多人之间的群聊6LkHTML5中文学习网 - HTML5先行者学习网
conversationQuery.whereEqualTo("attr.type", ConversationType_OneOne);6LkHTML5中文学习网 - HTML5先行者学习网
conversationQuery.findInBackground(new AVIMConversationQueryCallback(){6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(List<AVIMConversation> conversations, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
      // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
    } else if (null != conversations && conversations.size() > 0){6LkHTML5中文学习网 - HTML5先行者学习网
      // 已经有一个和 Bob 的对话存在,继续在这一对话中聊天6LkHTML5中文学习网 - HTML5先行者学习网
      ...6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
      // 不曾和 Bob 聊过,新建一个对话。!!**这里是重点**!!6LkHTML5中文学习网 - HTML5先行者学习网
      Map<String, Object> attr = new HashMap<String, Object>();6LkHTML5中文学习网 - HTML5先行者学习网
      attr.put("type", ConversationType_OneOne);6LkHTML5中文学习网 - HTML5先行者学习网
      imClient.createConversation(clientIds, attr, new AVIMConversationCreatedCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
        @Override6LkHTML5中文学习网 - HTML5先行者学习网
        public void done(AVIMConversation conversation, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
          if (null != conversation) {6LkHTML5中文学习网 - HTML5先行者学习网
            // 成功了!6LkHTML5中文学习网 - HTML5先行者学习网
          }6LkHTML5中文学习网 - HTML5先行者学习网
        }6LkHTML5中文学习网 - HTML5先行者学习网
      });6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

如何查询「对话」6LkHTML5中文学习网 - HTML5先行者学习网

如你所见,我们创建一个对话的时候,指定了成员(Tom 和 Bob)和一个额外的属性({type: 0})。这些数据保存到云端后,你在 控制台 -> 存储 -> 数据 里面会看到,_Conversation 表中增加了一条记录,新记录的 m 属性值为["Tom", "Bob"],attr 属性值为{"type":0}。如你所料,m 属性就是对应着成员列表,attr 属性就是用户增加的额外属性值(以对象的形式存储)。6LkHTML5中文学习网 - HTML5先行者学习网

与 AVObject 的检索方法一样,要检索这样的对话,我们需要通过 imClient.getQuery() 得到一个 AVIMConversationQuery 实例,然后调用 conversationQuery.withMembers() 来限定成员列表,调用 conversationQuery.whereEqualTo() 来限定额外的 attr 属性。按照 AVQuery 的惯例,限定额外的 type 条件的时候需要指定的属性名是 attr.type。6LkHTML5中文学习网 - HTML5先行者学习网
发送消息6LkHTML5中文学习网 - HTML5先行者学习网

建立好对话之后,要发送消息是很简单的:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
AVIMMessage message = new AVIMMessage();6LkHTML5中文学习网 - HTML5先行者学习网
message.setContent("hello");6LkHTML5中文学习网 - HTML5先行者学习网
conversation.sendMessage(message, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
       // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

好了,这样一条消息就发送过去了。但是问题来了,对于「Bob」而言,他怎么才能收到别人发给他的消息呢?6LkHTML5中文学习网 - HTML5先行者学习网

消息接收6LkHTML5中文学习网 - HTML5先行者学习网

在 Bob 这一端,要能接收到消息,需要如下几步:6LkHTML5中文学习网 - HTML5先行者学习网

1,进行初始化和登录,代码与发送端并无二致;6LkHTML5中文学习网 - HTML5先行者学习网

2,实现自己的 AVIMMessageHandler,响应新消息到达通知,主要是如下函数:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public void onMessage(AVIMMessage message, AVIMConversation conversation, AVIMClient client);6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

对于 Tom 发过来的消息,要显示出来,我们只需实现 onMessage 即可,示例代码如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
class CustomMessageHandler extends AVIMMessageHandler {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void onMessage(AVIMMessage message, AVIMConversation conversation, AVIMClient client) {6LkHTML5中文学习网 - HTML5先行者学习网
    // 新消息到来了。在这里增加你自己的处理代码。6LkHTML5中文学习网 - HTML5先行者学习网
    ...6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
AVIMMessageManager.registerDefaultMessageHandler(new CustomMessageHandler());6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

几个主要的回调接口6LkHTML5中文学习网 - HTML5先行者学习网

从上面的例子中可以看到,要接收到别人给你发送的消息,需要实现自己的 AVIMMessageHandler 类。从 v2 版开始,LeanCloud IM SDK 大量采用回调来反馈操作结果,但是对于一些被动的消息通知,则还是采用接口来实现的,包括:6LkHTML5中文学习网 - HTML5先行者学习网

当前网络出现变化6LkHTML5中文学习网 - HTML5先行者学习网
对话中有新的消息6LkHTML5中文学习网 - HTML5先行者学习网
对话中有新成员加入6LkHTML5中文学习网 - HTML5先行者学习网
对话中有成员离开6LkHTML5中文学习网 - HTML5先行者学习网
被邀请加入某对话6LkHTML5中文学习网 - HTML5先行者学习网
被踢出对话6LkHTML5中文学习网 - HTML5先行者学习网
LeanCloud IM SDK 内部使用了三种接口来响应这些事件。6LkHTML5中文学习网 - HTML5先行者学习网

网络事件响应接口(AVIMClientEventHandler)6LkHTML5中文学习网 - HTML5先行者学习网

主要用来处理网络变化事件,主要函数为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现本方法以处理网络断开事件6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @param client6LkHTML5中文学习网 - HTML5先行者学习网
   * @since 3.06LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onConnectionPaused(AVIMClient client);6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现本方法以处理网络恢复事件6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @since 3.06LkHTML5中文学习网 - HTML5先行者学习网
   * @param client6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onConnectionResume(AVIMClient client);6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

在网络中断的情况下,所有的消息收发和对话操作都会出现问题。6LkHTML5中文学习网 - HTML5先行者学习网

通过 AVIMClient.setClientEventHandler(AVIMClientEventHandler handler) 可以设定全局的 ClientEventHandler。6LkHTML5中文学习网 - HTML5先行者学习网

对话成员变化响应接口(AVIMConversationEventHandler)6LkHTML5中文学习网 - HTML5先行者学习网

主要用来处理对话中成员变化的事件,主要函数为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现本方法以处理聊天对话中的参与者离开事件6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @param client6LkHTML5中文学习网 - HTML5先行者学习网
   * @param conversation6LkHTML5中文学习网 - HTML5先行者学习网
   * @param members 离开的参与者6LkHTML5中文学习网 - HTML5先行者学习网
   * @param kickedBy 离开事件的发动者,有可能是离开的参与者本身6LkHTML5中文学习网 - HTML5先行者学习网
   * @since 3.06LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onMemberLeft(AVIMClient client,6LkHTML5中文学习网 - HTML5先行者学习网
      AVIMConversation conversation, List<String> members, String kickedBy);6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现本方法以处理聊天对话中的参与者加入事件6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @param client6LkHTML5中文学习网 - HTML5先行者学习网
   * @param conversation6LkHTML5中文学习网 - HTML5先行者学习网
   * @param members 加入的参与者6LkHTML5中文学习网 - HTML5先行者学习网
   * @param invitedBy 加入事件的邀请人,有可能是加入的参与者本身6LkHTML5中文学习网 - HTML5先行者学习网
   * @since 3.06LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onMemberJoined(AVIMClient client,6LkHTML5中文学习网 - HTML5先行者学习网
      AVIMConversation conversation, List<String> members, String invitedBy);6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现本方法来处理当前用户被踢出某个聊天对话事件6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @param client6LkHTML5中文学习网 - HTML5先行者学习网
   * @param conversation6LkHTML5中文学习网 - HTML5先行者学习网
   * @param kickedBy 踢出你的人6LkHTML5中文学习网 - HTML5先行者学习网
   * @since 3.06LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onKicked(AVIMClient client, AVIMConversation conversation,6LkHTML5中文学习网 - HTML5先行者学习网
      String kickedBy);6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现本方法来处理当前用户被邀请到某个聊天对话事件6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @param client6LkHTML5中文学习网 - HTML5先行者学习网
   * @param conversation 被邀请的聊天对话6LkHTML5中文学习网 - HTML5先行者学习网
   * @param operator 邀请你的人6LkHTML5中文学习网 - HTML5先行者学习网
   * @since 3.06LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onInvited(AVIMClient client, AVIMConversation conversation,6LkHTML5中文学习网 - HTML5先行者学习网
      String operator);6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

通过 AVIMMessageManager.setConversationEventHandler(AVIMConversationEventHandler handler) 可以设置全局的 ConversationEventHandler。6LkHTML5中文学习网 - HTML5先行者学习网

消息响应接口(MessageHandler)6LkHTML5中文学习网 - HTML5先行者学习网

主要用来处理新消息到达事件,主要的函数为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
  // 收到新的消息6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onMessage(AVIMMessage message, AVIMConversation conversation);6LkHTML5中文学习网 - HTML5先行者学习网
  // 自己发送的消息已经被对方接收6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public abstract void onMessageReceipt(AVIMMessage message, AVIMConversation conversation, AVIMClient client);6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

通过 AVIMMessageManager.registerDefaultMessageHandler(MessageHandler handler) 可以设置全局的 MessageHandler。6LkHTML5中文学习网 - HTML5先行者学习网

我们实现这三类接口,就可以处理所有的通知消息了(注意:LeanCloud IM SDK 内部实现了一个空的 AVIMMessageHandler,你可以从这里派生出进行实际处理的 handler)。6LkHTML5中文学习网 - HTML5先行者学习网

支持富媒体的聊天消息6LkHTML5中文学习网 - HTML5先行者学习网

上面的代码演示了如何发送简单文本信息,但是现在的交互方式已经越来越多样化,图片、语音、视频已是非常普遍的消息类型。v2 版的 LeanCloud IM SDK 已经可以很好地支持这些富媒体消息,具体说明如下:6LkHTML5中文学习网 - HTML5先行者学习网

基类:AVIMTypedMessage6LkHTML5中文学习网 - HTML5先行者学习网

所有富媒体消息的基类,其声明为6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
//SDK定义的消息类型,LeanCloud SDK 自身使用的类型是负数,所有正数留给开发者自定义扩展类型使用,0 作为「没有类型」被保留起来。6LkHTML5中文学习网 - HTML5先行者学习网
enum AVIMReservedMessageType {6LkHTML5中文学习网 - HTML5先行者学习网
  UnsupportedMessageType(0),6LkHTML5中文学习网 - HTML5先行者学习网
  TextMessageType(-1),6LkHTML5中文学习网 - HTML5先行者学习网
  ImageMessageType(-2),6LkHTML5中文学习网 - HTML5先行者学习网
  AudioMessageType(-3),6LkHTML5中文学习网 - HTML5先行者学习网
  VideoMessageType(-4),6LkHTML5中文学习网 - HTML5先行者学习网
  LocationMessageType(-5),6LkHTML5中文学习网 - HTML5先行者学习网
  FileMessageType(-6);6LkHTML5中文学习网 - HTML5先行者学习网
};6LkHTML5中文学习网 - HTML5先行者学习网
public abstract class AVIMTypedMessage extends AVIMMessage {6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMTypedMessage();6LkHTML5中文学习网 - HTML5先行者学习网
  public int getMessageType();6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public final String getContent();6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public final void setContent(String content);6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

文本消息(AVIMTextMessage)6LkHTML5中文学习网 - HTML5先行者学习网

AVIMTypedMessage 子类,表示一般的文本消息,其声明为6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
@AVIMMessageType(type = -1)6LkHTML5中文学习网 - HTML5先行者学习网
public class AVIMTextMessage extends AVIMTypedMessage {6LkHTML5中文学习网 - HTML5先行者学习网
  public String getText();6LkHTML5中文学习网 - HTML5先行者学习网

  public void setText(String text);6LkHTML5中文学习网 - HTML5先行者学习网

  public Map<String, Object> getAttrs();6LkHTML5中文学习网 - HTML5先行者学习网

  public void setAttrs(Map<String, Object> attr);6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网

6LkHTML5中文学习网 - HTML5先行者学习网

要发送文本消息,示例代码为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
AVIMTextMessage message = new AVIMTextMessage();6LkHTML5中文学习网 - HTML5先行者学习网
message.setText("hello");6LkHTML5中文学习网 - HTML5先行者学习网
conversation.sendMessage(message, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
       // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

图像消息(AVIMImageMessage)6LkHTML5中文学习网 - HTML5先行者学习网

AVIMTypedMessage 子类,支持发送图片和附带文本的混合消息,其声明为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class AVIMImageMessage extends AVIMFileMessage {6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMImageMessage();6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMImageMessage(String localPath) throws FileNotFoundException, IOException;6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMImageMessage(File localFile) throws FileNotFoundException, IOException;6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMImageMessage(AVFile file);6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 获取文件的metaData6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public Map<String, Object> getFileMetaData();6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 获取图片的高6LkHTML5中文学习网 - HTML5先行者学习网
   * 6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public int getHeight();6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 获取图片的宽度6LkHTML5中文学习网 - HTML5先行者学习网
   * 6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public int getWidth();6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
发送图片消息的示例代码为:6LkHTML5中文学习网 - HTML5先行者学习网
String localImagePath;6LkHTML5中文学习网 - HTML5先行者学习网
try {6LkHTML5中文学习网 - HTML5先行者学习网
  AVIMImageMessage message = new AVIMImageMessage(localImagePath);6LkHTML5中文学习网 - HTML5先行者学习网
  conversation.sendMessage(message, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
    @Override6LkHTML5中文学习网 - HTML5先行者学习网
    public void done(AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
      if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
        // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
      } else {6LkHTML5中文学习网 - HTML5先行者学习网
      }6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  });6LkHTML5中文学习网 - HTML5先行者学习网
} catch (Exception ex) {6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

接收到这样消息之后,开发者可以获取到若干图片元数据(width,height,图片 size,图片 format)和一个包含图片数据的 AVFile 对象。6LkHTML5中文学习网 - HTML5先行者学习网

音频消息(AVIMAudioMessage)6LkHTML5中文学习网 - HTML5先行者学习网

AVIMTypedMessage 子类,支持发送语音和附带文本的混合消息,其声明为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class AVIMAudioMessage extends AVIMFileMessage {6LkHTML5中文学习网 - HTML5先行者学习网
    public AVIMAudioMessage();6LkHTML5中文学习网 - HTML5先行者学习网
    public AVIMAudioMessage(String localPath) throws FileNotFoundException, IOException;6LkHTML5中文学习网 - HTML5先行者学习网
    public AVIMAudioMessage(File localFile) throws FileNotFoundException, IOException;   6LkHTML5中文学习网 - HTML5先行者学习网
    public AVIMAudioMessage(AVFile file);6LkHTML5中文学习网 - HTML5先行者学习网
    /**6LkHTML5中文学习网 - HTML5先行者学习网
     * 获取文件的metaData6LkHTML5中文学习网 - HTML5先行者学习网
     *6LkHTML5中文学习网 - HTML5先行者学习网
     * @return6LkHTML5中文学习网 - HTML5先行者学习网
     */6LkHTML5中文学习网 - HTML5先行者学习网
    @Override6LkHTML5中文学习网 - HTML5先行者学习网
    public Map<String, Object> getFileMetaData();6LkHTML5中文学习网 - HTML5先行者学习网

    /**6LkHTML5中文学习网 - HTML5先行者学习网
     * 获取音频的时长6LkHTML5中文学习网 - HTML5先行者学习网
     *6LkHTML5中文学习网 - HTML5先行者学习网
     * @return6LkHTML5中文学习网 - HTML5先行者学习网
     */6LkHTML5中文学习网 - HTML5先行者学习网
    public double getDuration();6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网

6LkHTML5中文学习网 - HTML5先行者学习网

发送音频消息的示例代码为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
String localAudioPath;6LkHTML5中文学习网 - HTML5先行者学习网
try {6LkHTML5中文学习网 - HTML5先行者学习网
  AVIMAudioMessage message = new AVIMAudioMessage(localAudioPath);6LkHTML5中文学习网 - HTML5先行者学习网
  conversation.sendMessage(message, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
    @Override6LkHTML5中文学习网 - HTML5先行者学习网
    public void done(AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
      if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
        // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
      } else {6LkHTML5中文学习网 - HTML5先行者学习网
      }6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  });6LkHTML5中文学习网 - HTML5先行者学习网
} catch (Exception ex) {6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

接收到这样消息之后,开发者可以获取到若干音频元数据(时长 duration、音频 size,音频 format)和一个包含音频数据的 AVFile 对象。6LkHTML5中文学习网 - HTML5先行者学习网

视频消息(AVIMVideoMessage)6LkHTML5中文学习网 - HTML5先行者学习网

AVIMTypedMessage 子类,支持发送视频和附带文本的混合消息,其声明为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class AVIMVideoMessage extends AVIMFileMessage {6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMVideoMessage();6LkHTML5中文学习网 - HTML5先行者学习网

  public AVIMVideoMessage(String localPath) throws FileNotFoundException, IOException;6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMVideoMessage(File localFile) throws FileNotFoundException, IOException;6LkHTML5中文学习网 - HTML5先行者学习网
  public AVIMVideoMessage(AVFile file);6LkHTML5中文学习网 - HTML5先行者学习网

  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 获取文件的metaData6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public Map<String, Object> getFileMetaData();6LkHTML5中文学习网 - HTML5先行者学习网

  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 获取时长6LkHTML5中文学习网 - HTML5先行者学习网
   *6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public double getDuration();6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网

6LkHTML5中文学习网 - HTML5先行者学习网

发送视频消息的示例代码为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
String localVideoPath;6LkHTML5中文学习网 - HTML5先行者学习网
try {6LkHTML5中文学习网 - HTML5先行者学习网
  AVIMVideoMessage message = new AVIMVideoMessage(localVideoPath);6LkHTML5中文学习网 - HTML5先行者学习网
  conversation.sendMessage(message, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
    @Override6LkHTML5中文学习网 - HTML5先行者学习网
    public void done(AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
      if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
        // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
      } else {6LkHTML5中文学习网 - HTML5先行者学习网
      }6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  });6LkHTML5中文学习网 - HTML5先行者学习网
} catch (Exception ex) {6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

接收到这样消息之后,开发者可以获取到若干视频元数据(时长 duration、视频 size,视频 format)和一个包含视频数据的 AVFile 对象。6LkHTML5中文学习网 - HTML5先行者学习网

地理位置消息(AVIMLocationMessage)6LkHTML5中文学习网 - HTML5先行者学习网

AVIMTypedMessage 子类,支持发送地理位置信息和附带文本的混合消息,其声明为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class AVIMLocationMessage extends AVIMTypedMessage {6LkHTML5中文学习网 - HTML5先行者学习网
  public String getText();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setText(String text);6LkHTML5中文学习网 - HTML5先行者学习网

  public Map<String, Object> getAttrs();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setAttrs(Map<String, Object> attr);6LkHTML5中文学习网 - HTML5先行者学习网

  public AVGeoPoint getLocation();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setLocation(AVGeoPoint location);6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网

6LkHTML5中文学习网 - HTML5先行者学习网

要发送位置消息的示例代码为:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
AVIMLocationMessage message = new AVIMLocationMessage();6LkHTML5中文学习网 - HTML5先行者学习网
message.setText("快点过来!");6LkHTML5中文学习网 - HTML5先行者学习网
message.setLocation(new AVGeoPoint(15.9, 56.4));6LkHTML5中文学习网 - HTML5先行者学习网
conversation.sendMessage(message, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
       // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

接收到这样的消息之后,开发者可以获取到具体的地理位置数据。6LkHTML5中文学习网 - HTML5先行者学习网

如何接收富媒体消息6LkHTML5中文学习网 - HTML5先行者学习网

新版 LeanCloud IM SDK 内部封装了对富媒体消息的支持,所有富媒体消息都是从 AVIMTypedMessage 派生出来的。发送的时候可以直接调用 conversation.sendMessage 函数。在接收端,我们也专门增加了一类回调接口:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class AVIMTypedMessageHandler<T extends AVIMTypedMessage> extends MessageHandler<T> {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void onMessage(T message, AVIMConversation conversation, AVIMClient client);6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void onMessageReceipt(T message, AVIMConversation conversation, AVIMClient client);6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

开发者可以编写自己的消息处理 handler,然后调用 AVIMMessageManager.registerMessageHandler(Class<? extends AVIMMessage> clazz, MessageHandler<?> handler) 函数来注册目标 handler。6LkHTML5中文学习网 - HTML5先行者学习网

LeanCloud IM SDK 内部消息分发的逻辑是这样的:对于收到的任一新消息,SDK 内部都会先解析消息的类型,根据类型找到开发者为这一类型注册的处理 handler,然后逐一调用这些 handler 的 onMessage 函数。如果没有找到专门处理这一类型消息的 handler,就会转交给 defaultHandler 处理。6LkHTML5中文学习网 - HTML5先行者学习网

这样一来,在开发者为 TypedMessage(及其子类) 指定了专门的 handler,也指定了全局的 defaultHandler 了的时候,如果发送端发送的是通用的 AVIMMessage 消息,那么接受端就是 AVIMMessageManager.registerDefaultMessageHandler()中指定的 handler 被调用;如果发送的是 AVIMTypedMessage(及其子类)的消息,那么接受端就是 AVIMMessageManager.registerMessageHandler()中指定的 handler 被调用。6LkHTML5中文学习网 - HTML5先行者学习网

接收端对于富媒体消息的通知处理代码片段如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
class MsgHandler extends AVIMTypedMessageHandler {6LkHTML5中文学习网 - HTML5先行者学习网
    @Override6LkHTML5中文学习网 - HTML5先行者学习网
    public void onMessage(AVIMTypedMessage message, AVIMConversation conversation, AVIMClient client) {6LkHTML5中文学习网 - HTML5先行者学习网
      getInstance().onMessage(conversation, message);6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
    @Override6LkHTML5中文学习网 - HTML5先行者学习网
    public void onMessageReceipt(AVIMTypedMessage message, AVIMConversation conversation, AVIMClient client) {6LkHTML5中文学习网 - HTML5先行者学习网
      getInstance().onMessageDelivered(message);6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
MsgHandler msgHandler = new MsgHandler();6LkHTML5中文学习网 - HTML5先行者学习网
AVIMMessageManager.registerMessageHandler(AVIMTypedMessage.class, msgHandler);6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

如何扩展自己的富媒体消息6LkHTML5中文学习网 - HTML5先行者学习网

继承于 AVIMTypedMessage,开发者也可以扩展自己的富媒体消息,这一部分属于高阶内容,大家有兴趣可以参看这篇文档,这里不再赘述。6LkHTML5中文学习网 - HTML5先行者学习网

群组聊天6LkHTML5中文学习网 - HTML5先行者学习网

与前面的单聊类似,群组聊天也需要先建立一个对话(AVIMConversation),然后发送、接收新的消息。6LkHTML5中文学习网 - HTML5先行者学习网

创建群组6LkHTML5中文学习网 - HTML5先行者学习网

和单聊类似,建立一个多人聊天的群组也是很简单的。例如:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
Map<String, Object> attr = new HashMap<String, Object>();6LkHTML5中文学习网 - HTML5先行者学习网
attr.put("type", ConversationType_Group);6LkHTML5中文学习网 - HTML5先行者学习网
imClient.createConversation(clientIds, attr, new AVIMConversationCreatedCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVIMConversation conversation, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != conversation) {6LkHTML5中文学习网 - HTML5先行者学习网
       // 成功了!6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

成功之后,我们就可以进入聊天界面了。6LkHTML5中文学习网 - HTML5先行者学习网

往群组发送消息6LkHTML5中文学习网 - HTML5先行者学习网

发送消息非常简单,与前面单聊的场景一样。6LkHTML5中文学习网 - HTML5先行者学习网

我们会注意到,AVIMConversation 还有一个发送消息的方法:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public void sendMessage(final AVIMMessage message, final int messageFlag,6LkHTML5中文学习网 - HTML5先行者学习网
      final AVIMConversationCallback callback)6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

而这里 flag 的定义有如下三种类型:6LkHTML5中文学习网 - HTML5先行者学习网

暂态消息(AVIMConversation.TRANSIENT_MESSAGE_FLAG)。这种消息不会被自动保存(以后在历史消息中无法找到它),也不支持延迟接收,离线用户更不会收到推送通知,所以适合用来做控制协议。譬如聊天过程中「某某正在输入中...」这样的状态信息,就适合通过暂态消息来发送。6LkHTML5中文学习网 - HTML5先行者学习网
普通消息(AVIMConversation.NONTRANSIENT_MESSAGE_FLAG)。这种消息就是我们最常用的消息类型,在 LeanCloud 云端会自动保存起来,支持延迟接收和离线推送,以后在历史消息中可以找到它。6LkHTML5中文学习网 - HTML5先行者学习网
待回执消息(AVIMConversation.RECEIPT_MESSAGE_FLAG)。这也是一种普通消息,只是消息被对方收到之后 LeanCloud 服务端会发送一个回执通知给发送方(这就是 AVIMMessageHandler 中 public void onMessageReceipt(AVIMMessage message, AVIMConversation conversation, AVIMClient client) 函数被调用的时机)。6LkHTML5中文学习网 - HTML5先行者学习网
接收群组消息6LkHTML5中文学习网 - HTML5先行者学习网

接收一个群组的消息,与接收单聊的消息也是一样的。6LkHTML5中文学习网 - HTML5先行者学习网

成员管理6LkHTML5中文学习网 - HTML5先行者学习网

在查询到聊天室成员之后,可以让用户邀请一些自己的朋友加入,作为管理员也可以剔除一些「可怕」的成员。6LkHTML5中文学习网 - HTML5先行者学习网
加入新成员的 API 如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
List<String> userIds = new ArrayList<String>();6LkHTML5中文学习网 - HTML5先行者学习网
userIds.add("A");6LkHTML5中文学习网 - HTML5先行者学习网
userIds.add("B");6LkHTML5中文学习网 - HTML5先行者学习网
userIds.add("C");6LkHTML5中文学习网 - HTML5先行者学习网
conversation.addMembers(userIds, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVException error) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != error) {6LkHTML5中文学习网 - HTML5先行者学习网
      // 加入失败,报错.6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
      // 发出邀请,此后新成员就可以看到这个对话中的所有消息了。6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

邀请成功以后,通知的流程是这样的:6LkHTML5中文学习网 - HTML5先行者学习网

    操作者(管理员)                    被邀请者                        其他人6LkHTML5中文学习网 - HTML5先行者学习网
1, 发出请求 addMembers6LkHTML5中文学习网 - HTML5先行者学习网
2,                               收到 onInvited 通知6LkHTML5中文学习网 - HTML5先行者学习网
3, 收到 onMemberJoined 通知      收到 onMemberJoined 通知      收到 onMemberJoined 通知6LkHTML5中文学习网 - HTML5先行者学习网
相应地,踢人时的调用 API 是:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
List<String> userIds = new ArrayList<String>();6LkHTML5中文学习网 - HTML5先行者学习网
userIds.add("A");6LkHTML5中文学习网 - HTML5先行者学习网
conversation.kickMembers(userIds, new AVIMConversationCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVException error) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != error) {6LkHTML5中文学习网 - HTML5先行者学习网
      // 失败,报错.6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
      // 成功。6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

踢人的通知流程如下:6LkHTML5中文学习网 - HTML5先行者学习网

    操作者(管理员)                被踢者                       其他人6LkHTML5中文学习网 - HTML5先行者学习网
1, 发出请求 kickMembers6LkHTML5中文学习网 - HTML5先行者学习网
2,                        收到 onKicked 通知6LkHTML5中文学习网 - HTML5先行者学习网
3, 收到 onMemberLeft 通知                             收到 onMemberLeft 通知6LkHTML5中文学习网 - HTML5先行者学习网
注意!6LkHTML5中文学习网 - HTML5先行者学习网
如果邀请、踢人操作发生的时候,被邀请者/被踢者当前不在线,那么通知消息并不会被离线缓存,所以他们再上线的时候将不会收到通知。6LkHTML5中文学习网 - HTML5先行者学习网
获取历史消息6LkHTML5中文学习网 - HTML5先行者学习网

LeanMessage 会将非暂态消息自动保存在云端,之后开发者可以通过 AVIMConversation 来获取该对话的所有历史消息。获取历史消息的 API 如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
String oldestMsgId;6LkHTML5中文学习网 - HTML5先行者学习网
long oldestMsgTimestamp;6LkHTML5中文学习网 - HTML5先行者学习网
conversation.queryMessages(oldestMsgId,oldestMsgTimestamp, limit, new AVIMHistoryMessageCallback(){6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(List<AVIMMessage> messages, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
      // 出错了:(6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
      // 成功6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

注意:6LkHTML5中文学习网 - HTML5先行者学习网
获取历史消息的时候,LeanCloud 云端是从某条消息开始,往前查找开发者指定的 N 条消息,返回给客户端。为此,获取历史消息需要传入三个参数:起始消息的 msgId,起始消息的发送时间戳,需要获取的消息条数。6LkHTML5中文学习网 - HTML5先行者学习网
通过这一 API 拿到的消息就是 AVIMMessage 或者 AVIMTypedMessage 实例数组,开发者可以像之前收到新消息通知一样处理。6LkHTML5中文学习网 - HTML5先行者学习网

启用离线消息推送(仅对 iOS 平台用户有效)6LkHTML5中文学习网 - HTML5先行者学习网

不管是单聊还是群聊,当用户 A 发出消息后,如果目标对话中有部分用户当前不在线,LeanCloud 云端可以提供离线推送的方式来提醒用户。这一功能默认是关闭的,你可以在 LeanCloud 应用控制台中开启它。开启方法如下:6LkHTML5中文学习网 - HTML5先行者学习网

登录 LeanCloud 应用控制台,选择正确的应用进入;6LkHTML5中文学习网 - HTML5先行者学习网
选择最顶端的「消息」服务,依次点击左侧菜单「实时消息」->「设置」;6LkHTML5中文学习网 - HTML5先行者学习网
在右侧「iOS 用户离线时的推送内容」下填好你要推送出去的消息内容,保存;6LkHTML5中文学习网 - HTML5先行者学习网
这样 iOS 平台上的用户就可以收到 Push Notification 了(当然,前提是应用本身申请到了 RemoteNotification 权限,也将正确的推送证书上传到了 LeanCloud 控制台)。6LkHTML5中文学习网 - HTML5先行者学习网

群组消息免打扰(仅对 iOS 平台用户有效)6LkHTML5中文学习网 - HTML5先行者学习网

不管是单聊还是群聊,对于发往普通的 Conversation 的普通消息,如果接收方当前不在线,LeanCloud 云端支持通过 Push Notification 的方式进行提醒。一般情况下这都是很好的,但是如果某个群组特别活跃,那离线用户就会收到过多的推送,会形成不小的干扰。6LkHTML5中文学习网 - HTML5先行者学习网
对此 LeanCloud IM 服务也允许单个用户来关闭/打开某个对话的离线推送功能。调用 API 如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
    if (open) {6LkHTML5中文学习网 - HTML5先行者学习网
        [_conversation muteWithCallback:^(BOOL succeeded, NSError *error) {6LkHTML5中文学习网 - HTML5先行者学习网
            ...6LkHTML5中文学习网 - HTML5先行者学习网
        }];6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
        [_conversation unmuteWithCallback:^(BOOL succeeded, NSError *error) {6LkHTML5中文学习网 - HTML5先行者学习网
            ...6LkHTML5中文学习网 - HTML5先行者学习网
        }];6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

搜索群组6LkHTML5中文学习网 - HTML5先行者学习网

不管是单聊,还是群聊,在 LeanCloud IM SDK 里面都是对话(Conversation)。我们给对话设置了如下几种属性:6LkHTML5中文学习网 - HTML5先行者学习网

conversationId,字符串,对话 id,只读,对话创建之后由 LeanCloud 云端赋予一个全局唯一的 id。6LkHTML5中文学习网 - HTML5先行者学习网
creator,字符串,对话创建者 id,只读,标识对话创建者信息6LkHTML5中文学习网 - HTML5先行者学习网
members,数组,对话参与者,这里记录了所有的参与者6LkHTML5中文学习网 - HTML5先行者学习网
name,字符串,对话的名字,optional,可用来对于群组命名6LkHTML5中文学习网 - HTML5先行者学习网
attributes,Map/Dict,自定义属性,optional,供开发者自己扩展用。6LkHTML5中文学习网 - HTML5先行者学习网
我们提供了专门的类,来搜索特定的群组。例如要搜索当前登录用户参与的所有群聊对话,其代码为6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
List<String> clients = new ArrayList<String>();6LkHTML5中文学习网 - HTML5先行者学习网
clients.add("Tom");6LkHTML5中文学习网 - HTML5先行者学习网
AVIMConversationQuery conversationQuery = imClient.getQuery();6LkHTML5中文学习网 - HTML5先行者学习网
conversationQuery.containsMember(clients);6LkHTML5中文学习网 - HTML5先行者学习网
// 之前有常量定义:6LkHTML5中文学习网 - HTML5先行者学习网
// const int ConversationType_OneOne = 0;6LkHTML5中文学习网 - HTML5先行者学习网
// const int ConversationType_Group = 1;6LkHTML5中文学习网 - HTML5先行者学习网
conversationQuery.whereEqualTo("attr.type", ConversationType_Group);6LkHTML5中文学习网 - HTML5先行者学习网
conversationQuery.findInBackground(new AVIMConversationQueryCallback(){6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(List<AVIMConversation> conversations, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
      // 出错了。。。6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
      // done!6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

AVIMConversationQuery 中设置条件的方法与 AVQuery 类似,具体可以参看其头文件。这里要强调的一点是,对于自定义属性的约束条件,属性名一定要以 attr 开头。6LkHTML5中文学习网 - HTML5先行者学习网

开放聊天室6LkHTML5中文学习网 - HTML5先行者学习网

开放聊天室(也叫暂态对话)可以用于很多地方,譬如弹幕、直播等等。在 LeanCloud IM SDK 中,开放聊天室是一类特殊的群组,它也支持创建、加入/踢出成员等操作,消息记录会被保存并可供获取;与普通群组不一样的地方具体体现为:6LkHTML5中文学习网 - HTML5先行者学习网

不支持查询成员列表,你可以通过相关 API 查询在线人数;6LkHTML5中文学习网 - HTML5先行者学习网
不支持离线消息、离线推送通知等功能;6LkHTML5中文学习网 - HTML5先行者学习网
没有成员加入、离开的通知;6LkHTML5中文学习网 - HTML5先行者学习网
一个用户一次登录只能加入一个开放聊天室,加入新的开放聊天室后会自动离开原来的聊天室;6LkHTML5中文学习网 - HTML5先行者学习网
加入后半小时内断网重连会自动加入原聊天室,超过这个时间则需要重新加入;6LkHTML5中文学习网 - HTML5先行者学习网
创建开放聊天室6LkHTML5中文学习网 - HTML5先行者学习网

和普通的群组类似,建立一个开放聊天室也是很简单的,只是在 AVIMClient.createConversation(conversationMembers, name, attributes, isTransient, callback) 中我们需要传入 isTransient=true 选项。例如:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
Map<String, Object> attr = new HashMap<String, Object>();6LkHTML5中文学习网 - HTML5先行者学习网
attr.put("type", ConversationType_Group);6LkHTML5中文学习网 - HTML5先行者学习网
imClient.createConversation(clientIds, name, attr, true, new AVIMConversationCreatedCallback() {6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(AVIMConversation conversation, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != conversation) {6LkHTML5中文学习网 - HTML5先行者学习网
       // 成功了!6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

加入成功之后,我们就可以进入聊天界面了。开放聊天室的其他操作,都与普通群组操作一样。6LkHTML5中文学习网 - HTML5先行者学习网

查询在线人数6LkHTML5中文学习网 - HTML5先行者学习网

通过 AVIMConversation.getMemberCount() 方法可以实时查询开放聊天室的在线人数。示例代码如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
conversation.getMemberCount(new AVIMConversationMemberCountCallback(){6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public void done(Integer memberCount, AVException e) {6LkHTML5中文学习网 - HTML5先行者学习网
    if (null != e) {6LkHTML5中文学习网 - HTML5先行者学习网
      // 出错了:(6LkHTML5中文学习网 - HTML5先行者学习网
    } else {6LkHTML5中文学习网 - HTML5先行者学习网
      // 成功,此时 memberCount 的数值就是实时在线人数6LkHTML5中文学习网 - HTML5先行者学习网
    }6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
});6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

签名和安全6LkHTML5中文学习网 - HTML5先行者学习网

为了满足开发者对权限和认证的要求,LeanCloud 还设计了操作签名的机制。我们可以在 LeanCloud 应用控制台中的「设置」->「应用选项」->「聊天推送」下面勾选「聊天服务签名认证」来启用签名(强烈推荐这样做)。启用后,所有的用户登录、对话创建/加入、邀请成员、踢出成员等操作都需要验证签名,这样开发者就可以对消息进行充分的控制。6LkHTML5中文学习网 - HTML5先行者学习网

客户端这边究竟该如何使用呢?我们只需要实现 SignatureFactory 接口,然后在用户登录之前,把这个接口的实例赋值给 AVIMClient 即可(AVIMClient.setSignatureFactory(factory))。6LkHTML5中文学习网 - HTML5先行者学习网

设定了 signatureFactory 之后,对于需要鉴权的操作,LeanCloud IM SDK 与服务器端通讯的时候都会带上应用自己生成的 Signature 信息,LeanCloud 云端会使用 app 的 masterKey 来验证信息的有效性,保证聊天渠道的安全。6LkHTML5中文学习网 - HTML5先行者学习网

对于 SignatureFactory 接口,我们只需要实现这两个函数即可:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现一个基础签名方法 其中的签名算法会在SessionManager和AVIMClient(V2)中被使用6LkHTML5中文学习网 - HTML5先行者学习网
   * 6LkHTML5中文学习网 - HTML5先行者学习网
   * @param peerId6LkHTML5中文学习网 - HTML5先行者学习网
   * @param watchIds6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   * @throws SignatureException 如果签名计算中间发生任何问题请抛出本异常6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public Signature createSignature(String peerId, List<String> watchIds) throws SignatureException;6LkHTML5中文学习网 - HTML5先行者学习网
  /**6LkHTML5中文学习网 - HTML5先行者学习网
   * 实现AVIMConversation相关的签名计算6LkHTML5中文学习网 - HTML5先行者学习网
   * 6LkHTML5中文学习网 - HTML5先行者学习网
   * @param conversationId6LkHTML5中文学习网 - HTML5先行者学习网
   * @param clientId6LkHTML5中文学习网 - HTML5先行者学习网
   * @param targetIds 操作所对应的数据6LkHTML5中文学习网 - HTML5先行者学习网
   * @param action 操作6LkHTML5中文学习网 - HTML5先行者学习网
   * @return6LkHTML5中文学习网 - HTML5先行者学习网
   * @throws SignatureException 如果签名计算中间发生任何问题请抛出本异常6LkHTML5中文学习网 - HTML5先行者学习网
   */6LkHTML5中文学习网 - HTML5先行者学习网
  public Signature createConversationSignature(String conversationId, String clientId,6LkHTML5中文学习网 - HTML5先行者学习网
      List<String> targetIds, String action) throws SignatureException;6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

createSignature 函数会在用户登录的时候被调用,createConversationSignature 会在对话创建/加入、邀请成员、踢出成员等操作时被调用。6LkHTML5中文学习网 - HTML5先行者学习网

你需要做的就是按照前文所述的签名算法实现签名,其中 Signature 声明如下:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class Signature {6LkHTML5中文学习网 - HTML5先行者学习网
  public List<String> getSignedPeerIds();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setSignedPeerIds(List<String> signedPeerIds);6LkHTML5中文学习网 - HTML5先行者学习网
  public String getSignature();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setSignature(String signature);6LkHTML5中文学习网 - HTML5先行者学习网
  public long getTimestamp();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setTimestamp(long timestamp);6LkHTML5中文学习网 - HTML5先行者学习网
  public String getNonce();6LkHTML5中文学习网 - HTML5先行者学习网
  public void setNonce(String nonce);6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

其中四个属性分别是:6LkHTML5中文学习网 - HTML5先行者学习网

signature 签名6LkHTML5中文学习网 - HTML5先行者学习网
timestamp 时间戳,单位秒6LkHTML5中文学习网 - HTML5先行者学习网
nonce 随机字符串 nonce6LkHTML5中文学习网 - HTML5先行者学习网
signedPeerIds 放行的 clientId 列表,v2 中已经废弃不用6LkHTML5中文学习网 - HTML5先行者学习网
下面的代码展示了基于 LeanCloud 云代码进行签名时,客户端的实现片段:6LkHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
6LkHTML5中文学习网 - HTML5先行者学习网
public class KeepAliveSignatureFactory implements SignatureFactory {6LkHTML5中文学习网 - HTML5先行者学习网
 @Override6LkHTML5中文学习网 - HTML5先行者学习网
 public Signature createSignature(String peerId, List<String> watchIds) {6LkHTML5中文学习网 - HTML5先行者学习网
   Map<String,Object> params = new HashMap<String,Object>();6LkHTML5中文学习网 - HTML5先行者学习网
   params.put("self_id",peerId);6LkHTML5中文学习网 - HTML5先行者学习网
   params.put("watch_ids",watchIds);6LkHTML5中文学习网 - HTML5先行者学习网
   try{6LkHTML5中文学习网 - HTML5先行者学习网
     Object result =  AVCloud.callFunction("sign",params);6LkHTML5中文学习网 - HTML5先行者学习网
     if(result instanceof Map){6LkHTML5中文学习网 - HTML5先行者学习网
       Map<String,Object> serverSignature = (Map<String,Object>) result;6LkHTML5中文学习网 - HTML5先行者学习网
       Signature signature = new Signature();6LkHTML5中文学习网 - HTML5先行者学习网
       signature.setSignature((String)serverSignature.get("signature"));6LkHTML5中文学习网 - HTML5先行者学习网
       signature.setTimestamp((Long)serverSignature.get("timestamp"));6LkHTML5中文学习网 - HTML5先行者学习网
       signature.setNonce((String)serverSignature.get("nonce"));6LkHTML5中文学习网 - HTML5先行者学习网
       return signature;6LkHTML5中文学习网 - HTML5先行者学习网
     }6LkHTML5中文学习网 - HTML5先行者学习网
   }catch(AVException e){6LkHTML5中文学习网 - HTML5先行者学习网
     throw (SignatureFactory.SignatureException) e;6LkHTML5中文学习网 - HTML5先行者学习网
   }6LkHTML5中文学习网 - HTML5先行者学习网
   return null;6LkHTML5中文学习网 - HTML5先行者学习网
 }6LkHTML5中文学习网 - HTML5先行者学习网
  @Override6LkHTML5中文学习网 - HTML5先行者学习网
  public Signature createConversationSignature(String convId, String peerId, List<String> targetPeerIds,String action){6LkHTML5中文学习网 - HTML5先行者学习网
   Map<String,Object> params = new HashMap<String,Object>();6LkHTML5中文学习网 - HTML5先行者学习网
   params.put("self_id",peerId);6LkHTML5中文学习网 - HTML5先行者学习网
   params.put("group_id",convId);6LkHTML5中文学习网 - HTML5先行者学习网
   params.put("group_peer_ids",targetPeerIds);6LkHTML5中文学习网 - HTML5先行者学习网
   params.put("action",action);6LkHTML5中文学习网 - HTML5先行者学习网
   try{6LkHTML5中文学习网 - HTML5先行者学习网
     Object result = AVCloud.callFunction("group_sign",params);6LkHTML5中文学习网 - HTML5先行者学习网
     if(result instanceof Map){6LkHTML5中文学习网 - HTML5先行者学习网
        Map<String,Object> serverSignature = (Map<String,Object>) result;6LkHTML5中文学习网 - HTML5先行者学习网
        Signature signature = new Signature();6LkHTML5中文学习网 - HTML5先行者学习网
        signature.setSignature((String)serverSignature.get("signature"));6LkHTML5中文学习网 - HTML5先行者学习网
        signature.setTimestamp((Long)serverSignature.get("timestamp"));6LkHTML5中文学习网 - HTML5先行者学习网
        signature.setNonce((String)serverSignature.get("nonce"));6LkHTML5中文学习网 - HTML5先行者学习网
        return signature;6LkHTML5中文学习网 - HTML5先行者学习网
     }6LkHTML5中文学习网 - HTML5先行者学习网
   }catch(AVException e){6LkHTML5中文学习网 - HTML5先行者学习网
     throw (SignatureFactory.SignatureException) e;6LkHTML5中文学习网 - HTML5先行者学习网
   }6LkHTML5中文学习网 - HTML5先行者学习网
   return null;6LkHTML5中文学习网 - HTML5先行者学习网
  }6LkHTML5中文学习网 - HTML5先行者学习网
}6LkHTML5中文学习网 - HTML5先行者学习网
6LkHTML5中文学习网 - HTML5先行者学习网

LeanCloud IM SDK 专注做好底层的通讯服务,有更多可以定制化的地方,譬如说:6LkHTML5中文学习网 - HTML5先行者学习网

账户系统和 IM 系统是分离的;6LkHTML5中文学习网 - HTML5先行者学习网
消息变成离线推送的时候,推送内容开发者是可以定制的;6LkHTML5中文学习网 - HTML5先行者学习网
通过 web hook,开发者可以对消息进行更多处理;6LkHTML5中文学习网 - HTML5先行者学习网
聊天过程中通过消息鉴权机制,开发者可以有更多控制;6LkHTML5中文学习网 - HTML5先行者学习网
因为缺少 UI 组件,实事求是地讲在新用户接入成本可能稍高,但是在业务规模扩大、产品需求变多之后,相信大家会越来越喜欢 LeanCloud 这种自由灵活的使用体验,以及稳定迅捷的服务质量。6LkHTML5中文学习网 - HTML5先行者学习网

以上所述就是本文的全部内容了,希望大家能够喜欢。6LkHTML5中文学习网 - HTML5先行者学习网

请您花一点时间将文章分享给您的朋友或者留下评论。我们将会由衷感谢您的支持!6LkHTML5中文学习网 - HTML5先行者学习网

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助