|
1 | | -# jmessage-react-plugin |
2 | | - |
| 1 | +# jmessage-react-plugin (iOS 尚未支持) |
3 | 2 | ##Android |
4 | 3 |
|
5 | | -####这是一个使用JMessage-sdk的混合的React Native应用,在本项目中使用了[Redux架构](http://camsong.github.io/redux-in-chinese/)来管理状态。先来看一下效果图: |
6 | | - |
7 | | - |
| 4 | +####这是一个使用JMessage-sdk的混合的React Native应用,目前实现了收发文字消息。 |
8 | 5 |
|
9 | | -目前还没有实现收发消息,后续会陆续实现。。-_- |
| 6 | +#### 安装 |
| 7 | +``` |
| 8 | +npm install jmessage-react-plugin --save |
| 9 | +react-native link |
| 10 | +``` |
| 11 | +安装完毕后,在 MainApplication 中加上 JMessagePackage 即可。 |
| 12 | +``` |
| 13 | + @Override |
| 14 | + protected List<ReactPackage> getPackages() { |
| 15 | + return Arrays.<ReactPackage>asList( |
| 16 | + new MainReactPackage(), |
| 17 | + new JMessageReactPackage(), |
| 18 | + ); |
| 19 | + } |
| 20 | +``` |
10 | 21 |
|
11 | | -####Android用法 |
12 | | -- 下载并解压这个项目的zip |
13 | | -- 在初始化好的React项目中将app文件夹替换为你刚刚解压的app文件夹(jmessage-react-plugin-master/android/app)(如果你还没有初始化,[参考这个](https://facebook.github.io/react-native/docs/getting-started.html#content)) |
14 | | -- 修改android文件夹下的build.gradle将dependencies下的classpath修改为你当前Android Studio所用的版本 |
15 | | -- 修改app文件夹下的build.gradle,将compile "com.facebook.react:react-native:0.23.0"修改为你当前的版本 |
16 | | -- 在AndroidManifest中更改PackageName和build.gradle中的applicationId为你自己的包名 |
17 | | -- 在AndroidManifest中将appKey替换为你在极光推送控制台注册的应用的appKey,如果没有,可以[前往注册](https://www.jpush.cn/) |
18 | | -- 运行app |
| 22 | +#### example 使用 |
| 23 | +``` |
| 24 | +npm install react-native-jchat-demo |
| 25 | +react-native run-android |
| 26 | +``` |
19 | 27 |
|
20 | 28 | 关于jmessage-sdk的相关接口说明可以参考: |
21 | 29 | #####[极光IM Android SDK概述](http://docs.jpush.io/client/im_sdk_android/) |
22 | 30 |
|
23 | 31 | #####[IM Android SDK Java docs](http://docs.jpush.io/client/im_android_api_docs/) |
24 | 32 |
|
25 | | -####jmessage-react-plugin Android的项目结构说明 |
26 | | -#####JS部分 |
27 | | -除了入口index.android.js之外,都放在react-native-android文件夹下 |
28 | | -- actions 充当调用jmessage-sdk动作的发起者,action可以再抽象出一个中间件,但本项目中没有这样做 |
29 | | -- containers 所有Component的集合,负责界面的更新与发起actions |
30 | | -- reducers 根据一个action返回一个新的state,负责state的更新 |
31 | | -- store 绑定actions和reducers |
| 33 | +####jmessage-react-plugin Android 的项目结构说明 |
| 34 | +#####JS 部分 |
| 35 | +除了入口 index.android.js 之外,都放在 react-native-android 文件夹下 |
32 | 36 |
|
33 | 37 | #####Native部分 |
34 | | -- entity 根据需求抽象出的一些实体类,主要是为了使用Gson转换为json字符串传到JS(如果是纯React Native应用,则不需要如此,直接请求服务端即可) |
| 38 | +- entity 根据需求抽象出的一些实体类,主要是为了使用 Gson 转换为 json 字符串传到 JS(如果是纯 React Native 应用,则不需要如此,直接请求服务端即可) |
35 | 39 | - tools 主要是一些工具类 |
36 | | -- 其他 包括Native入口类以及NativeModule等 |
| 40 | +- 其他 包括 Native 入口类以及 NativeModule 等 |
37 | 41 |
|
38 | 42 | ####接口调用 |
39 | | -#####在JS中调用jmessage-sdk的接口 |
40 | | -> actions/conversationActions.js |
41 | 43 |
|
| 44 | +#####在 JS 中调用 jmessage-sdk 的接口详情 |
42 | 45 | ``` |
43 | | -export function loadConversations() { |
44 | | - return dispatch => { |
45 | | - type: types.INITIAL_CONVERSATION_LIST, |
46 | | - JMessageHelper.getConvList((result) => { |
47 | | - dispatch({ |
48 | | - type: types.LOAD_CONVERSATIONS, |
49 | | - convList: JSON.parse(result), |
50 | | - }); |
51 | | - }, () => { |
52 | | - dispatch({ |
53 | | - type: types.LOAD_ERROR, |
54 | | - convList: [] |
55 | | - }) |
56 | | - }); |
57 | | - } |
58 | | -} |
59 | | -``` |
60 | | - |
61 | | -这个action实际上通过JMessageHelper这个NativeModule调用了getConvList()这个方法: |
62 | | -> JMessageHelper.java |
63 | | -
|
64 | | -``` |
65 | | - /** |
66 | | - * JS端调用的获取所有会话的方法 |
67 | | - * @param successCallback 回调返回一个Map对象 |
68 | | - */ |
69 | | - @ReactMethod |
70 | | - public void getConvList(Callback successCallback, Callback errorCallback) { |
71 | | - mContext = getCurrentActivity(); |
72 | | - List<Conversation> data = JMessageClient.getConversationList(); |
73 | | - //对会话列表进行时间排序 |
74 | | - if (data != null) { |
75 | | - if (data.size() > 1) { |
76 | | - SortConvList sortList = new SortConvList(); |
77 | | - Collections.sort(data, sortList); |
| 46 | +const JMessageModule = NativeModules.JMessageModule; |
| 47 | +``` |
| 48 | +- 加载 conversations: |
| 49 | +``` |
| 50 | +JMessageModule.getConvList().then((list) => { |
| 51 | + _convList = JSON.parse(list); |
| 52 | + this.setState({ |
| 53 | + dataSource: _ds.cloneWithRows(_convList), |
| 54 | + fetching: false |
| 55 | + }); |
| 56 | + }).catch((e) => { |
| 57 | + console.log(e); |
| 58 | + this.setState({ |
| 59 | + fetching: false |
| 60 | + }); |
| 61 | + }); |
| 62 | +``` |
| 63 | +- 接收消息 |
| 64 | +``` |
| 65 | +const RECEIVE_MSG_EVENT = "receiveMsgEvent"; |
| 66 | +
|
| 67 | +componentDidMount() { |
| 68 | + DeviceEventEmitter.addListener(RECEIVE_MSG_EVENT, (map) => { |
| 69 | + console.log("收到消息: " + map.message); |
| 70 | + let conversation = JSON.parse(map.conversation); |
| 71 | + for (let conv in _convList) { |
| 72 | + if (conv.username === conversation.username || conv.groupId === conversation.groupId) { |
| 73 | + conv = conversation; |
| 74 | + } |
78 | 75 | } |
79 | | - //模拟将从服务器端返回的数据解析为JSON字符串传到JS端 |
80 | | - //如果是纯React应用应该在JS端直接fetch服务端的数据,由于目前使用的是jmessage-sdk,所以采用这种方法 |
81 | | - ConversationToJSON convToJSON = new ConversationToJSON(mContext, data); |
82 | | - String result = convToJSON.getResult(); |
83 | | - Log.i(TAG,"Result: " + result); |
84 | | - successCallback.invoke(result); |
85 | | - } else { |
86 | | - errorCallback.invoke(); |
87 | | - } |
| 76 | + let newData = JSON.parse(JSON.stringify(_convList)); |
| 77 | + newData.sort(this.by("date")); |
| 78 | + this.setState({ |
| 79 | + dataSource: _ds.cloneWithRows(newData) |
| 80 | + }); |
| 81 | + _convList = newData; |
| 82 | + }); |
88 | 83 | } |
89 | 84 | ``` |
| 85 | +- 发送消息 |
| 86 | +``` |
| 87 | +const {username, appKey, groupId} = this.props; |
| 88 | + JMessageModule.sendTxtMsg(username, appKey, groupId, this.state.inputContent) |
| 89 | + .then((msg) => { |
| 90 | + console.log("Sending text message: " + msg); |
| 91 | + this.msgArr.push(JSON.parse(msg)); |
| 92 | + console.log("msgArr: " + this.msgArr); |
| 93 | + this.setState({ |
| 94 | + dataSource: this.state.ds.cloneWithRows(this.msgArr), |
| 95 | + inputContent: "" |
| 96 | + }); |
| 97 | + if (this.listView !== null) { |
| 98 | + this.listView.scrollToEnd(); |
| 99 | + } |
| 100 | + }).catch((e) => { |
| 101 | + console.log(e); |
| 102 | + this.setState({ |
| 103 | + inputContent: "" |
| 104 | + }); |
| 105 | + }); |
| 106 | +``` |
| 107 | +发送消息后还需要监听发送状态: |
| 108 | + |
| 109 | +``` |
| 110 | +const SEND_MSG_RESULT = "sendMsgResult"; |
| 111 | +DeviceEventEmitter.addListener(SEND_MSG_RESULT, this.sendMsgResult); |
| 112 | +sendMsgResult = (msg) => { |
| 113 | + var message = JSON.parse(msg); |
| 114 | + for (var i = this.msgArr.length - 1; i >= 0; i--) { |
| 115 | + if (this.msgArr[i].msgId === message.msgId) { |
| 116 | + this.msgArr[i].sendState = message.sendState; |
| 117 | + } |
| 118 | + } |
| 119 | + let newData = JSON.parse(JSON.stringify(this.msgArr)); |
| 120 | + this.setState({ |
| 121 | + dataSource: this.state.ds.cloneWithRows(newData) |
| 122 | + }); |
| 123 | + this.msgArr = newData; |
| 124 | + }; |
| 125 | +``` |
| 126 | + |
| 127 | +- 分页加载消息 |
| 128 | + |
| 129 | +``` |
| 130 | +JMessageModule.getMessageFromNewest(username, appKey, groupId, this.START, this.PAGE_MSG_COUNT) |
| 131 | + .then((result) => { |
| 132 | + if ("" === result) { |
| 133 | + console.log("No last page"); |
| 134 | + this.setState({ |
| 135 | + fetching: false |
| 136 | + }); |
| 137 | + return; |
| 138 | + } |
| 139 | + let msgData = JSON.parse(result); |
| 140 | + msgData.reverse(); |
| 141 | + this.msgArr = this.msgArr.concat(msgData); |
| 142 | + this.MSG_OFFSET = this.START + msgData.length; |
| 143 | + this.START = this.MSG_OFFSET; |
| 144 | + this.setState({ |
| 145 | + fetching: false, |
| 146 | + dataSource: this.state.ds.cloneWithRows(this.msgArr) |
| 147 | + }); |
| 148 | + }).catch((e) => { |
| 149 | + console.log(e); |
| 150 | + this.setState({ |
| 151 | + fetching: false |
| 152 | + }); |
| 153 | + }); |
| 154 | +``` |
| 155 | + |
| 156 | +- 进入会话(进入会话后,通知栏不会展示此会话中收到的消息) |
90 | 157 |
|
91 | | -在Native里就可以直接调用jmessage-sdk的接口了,然后将得到的数据通过CallBack传递到JS。其他的接口调用也基本上类似。 |
| 158 | +``` |
| 159 | +JMessageModule.enterConversation(username, appKey, groupId); |
| 160 | +``` |
| 161 | +- 添加好友(无好友模式) |
92 | 162 |
|
| 163 | +``` |
| 164 | +JMessageModule.addFriend(inputTxt).then((result) => { |
| 165 | + var newDs = JSON.parse(result); |
| 166 | + _convList = [newDs, ..._convList]; |
| 167 | + this.setState({ |
| 168 | + dataSource: _ds.cloneWithRows(_convList) |
| 169 | + }); |
| 170 | + }).catch((e) => { |
| 171 | + console.log(e); |
| 172 | + }); |
| 173 | +``` |
93 | 174 | ##关于升级React Native |
94 | 175 | **进入当前项目的目录** |
95 | 176 | - 在命令行中使用: |
|
0 commit comments