自定义消息类型
重要
本文适用于 SDK 5.6.7 及之后版本。如果您的 SDK 版本 < 5.6.7,请使用自定义消息(旧版)。
提示
SDK 5.6.7 版本开始,MessageContent.java
中封装了 user
(用户信息),mentionedInfo
(@人信息) ,extra
(附加信息)字段的编解码及序列化方法,实现自定义消息时可直接调用父类的解析方法,无需开发者自行解析。新旧版本自定义消息可兼容互通。已使用旧版自定义消息客户,如需新增自定义消息类型,推荐使用新版自定义消息。
除了使用 IMLib SDK 内置消息外,还可以创建自定义消息类型。
您需要根据业务需求来选择自定义消息类型继承的消息基类:
- MessageContent:即普通类型消息内容。例如在 SDK 内置消息类型中的文本消息和位置消息。
- MediaMessageContent:即媒体类型消息。媒体类型消息内容继承自 MessageContent,并在其基础上增加了对多媒体文件的处理逻辑。在发送和接收消息时,SDK 会判断消息类型是否为多媒体类型消息,如果是多媒体类型,则会触发上传或下载多媒体文件流程。
关于消息实体类与消息内容的更多介绍,可参见消息介绍。
提示
自定义消息的类型、消息结构需要确保多端一致,否则将出现无法互通的问题。
创建自定义消息
SDK 不负责定义和解析自定义消息的具体内容,您需要自行实现。
自定义消息类型的 @MessageTag
(MessageTag)决定该消息类型的唯一标识(objectname
),以及是否存储、是否展示、是否计入消息未读数等属性。
自定义消息示例代码:普通消息
以 下为自定义普通消息的完整示例代码。
Java
// 1. 自定义消息实现 MessageTag 注解
@MessageTag(value = "app:txtcontent", flag = MessageTag.ISCOUNTED)
public class MyTextContent extends MessageContent {
// <editor-fold desc="* 2. 自身内部变量,可以有多个">
private static final String TAG = "appTextContent";
private String content;
// </editor-fold>
// <editor-fold desc="* 3. 对外构造方法">
private MyTextContent() {}
// 快速构建消息对象方法
public static MyTextContent obtain(String content) {
MyTextContent msg = new MyTextContent();
msg.content = content;
return msg;
}
// </editor-fold>
// <editor-fold desc="* 4. 二进制 Encode & decode 编解码方法">
/**
* 将本地消息对象序列化为消息数据。
*
* @return 消息数据。
*/
@Override
public byte[] encode() {
//此处以 需要携带 “用户信息” 或者 “@ 人” 信息为例
JSONObject jsonObj = super.getBaseJsonObject();
try {
// 将所有自定义消息的内容,都序列化至 json 对象中
jsonObj.put("content", this.content);
} catch (JSONException e) {
Log.e(TAG, "JSONException " + e.getMessage());
}
try {
return jsonObj.toString().getBytes("UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "UnsupportedEncodingException ", e);
}
return null;
}
/** 创建 MyTextContent(byte[] data) 带有 byte[] 的构造方法用于解析消息内容. */
public MyTextContent(byte[] data) {
if (data == null) {
return;
}
String jsonStr = null;
try {
jsonStr = new String(data, "UTF-8");
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "UnsupportedEncodingException ", e);
}
if (jsonStr == null) {
Log.e(TAG, "jsonStr is null ");
return;
}
try {
JSONObject jsonObj = new JSONObject(jsonStr);
//此处以需要携带 “用户信息” 或者 “@ 人” 信息为例
super.parseBaseJsonObject(jsonObj);
// 将所有自定义变量从收到的 json 解析并赋值
if (jsonObj.has("content")) {
content = jsonObj.optString("content");
}
} catch (JSONException e) {
Log.e(TAG, "JSONException " + e.getMessage());
}
}
// </editor-fold>
// <editor-fold desc="* 5. Parcel 的序列化方法">
@Override
public void writeToParcel(Parcel dest, int i) {
// 对消息属性进行序列化,将类的数据写入外部提供的 Parcel 中,此处以需要序列化"用户信息","@信息" 等为例
super.writeToBaseInfoParcel(dest);
ParcelUtils.writeToParcel(dest, content);
}
/**
* 构造函数。
*
* @param in 初始化传入的 Parcel。
*/
public MyTextContent(Parcel in) {
// 此处以需要序列化"用户信息","@信息" 等为例
super.readFromBaseInfoParcel(in);
setContent(ParcelUtils.readFromParcel(in));
}
public static final Creator<MyTextContent> CREATOR =
new Creator<MyTextContent>() {
public MyTextContent createFromParcel(Parcel source) {
return new MyTextContent(source);
}
public MyTextContent[] newArray(int size) {
return new MyTextContent[size];
}
};
@Override
public int describeContents() {
return 0;
}
// </editor-fold>
// <editor-fold desc="* 6. get & set 方法">
/**
* 设置文字消息的内容。
*
* @param content 文字消息的内容。
*/
public void setContent(String content) {
this.content = content;
}
public String getContent() {
return content;
}
// </editor-fold>
}