看这篇文章之前,我们可以先看看效果图:
我们这篇文章的重点在于数据的请求,界面的实现可以查看我之前的一篇文章类似QQ聊天界面
然后开始我们的正题,我们的思路很简单:将我们的问题发送给图灵机器人的服务器,服务器返回给我们数据,然后解析显示。这里我们的数据请求和数据解析都交给okhttp这个开源网络请求框架,这里是github地址。
- okhttp的优点,即我们为什么使用okhttp
- 支持HTTP/2, HTTP/2通过使用多路复用技术在一个单独的TCP连接上支持并发, 通过在一个连接上一次性发送多个请求来发送或接收数据
- 如果HTTP/2不可用, 连接池复用技术也可以极大减少延时
- 支持GZIP, 可以压缩下载体积
- 响应缓存可以直接避免重复请求
- 会从很多常用的连接问题中自动恢复
- 如果您的服务器配置了多个IP地址, 当第一个IP连接失败的时候, OkHttp会自动尝试下一个IP
- OkHttp还处理了代理服务器问题和SSL握手失败问题
当然你也可以使用HttpUrlConnection和HttpClient,但是这里我更喜欢使用okhttp。
要使用图灵机器人我们需要注册他的账号,获得开发者的key,注册这里就不讲了,我是用于测试的免费版,功能也很完整了,一天5000次的免费请求也是足够了。
然后我们查看api的介绍发现,它官方鼓励使用post的方式请求数据,所以这里我们用okhttp自己封装一个方法,方便我们之后的请求:
/***
* post请求数据
* @param url 请求地址
* @param keys 请求参数的key值数组
* @param values 请求参数的key对应的value数组
* @return 返回请求结果
* @throws IOException
*/
public String sendPost(String url, String[] keys, String[] values) throws IOException {
//第一步
client = new OkHttpClient();
//第二步
FormBody.Builder builder = new FormBody.Builder();
//拼接请求体,和get方式的区别就在这里
for (int i = 0; i < keys.length; i++) {
builder.add(keys[i], values[i]);
}
RequestBody body = builder.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
/*Call call = client.newCall(request);
//第三步
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
Log.e("Exception", e.toString());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
strResponse = response.body().string();
Log.i("result", strResponse);
}
});*/
Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException();
}
strResponse = response.body().string();
return strResponse;
}
你可以看见上面我注销了一段代码,因为我在测试的时候发现它返回的JSON结果一直为空,一直找不到原因,后来想明白过来,这个请求成功的回调方法onResponse是在一个新的线程中执行的,是一个异步操作,所以如果用这种方式,还没获取到值就已经返回null值了。所以我们改用同步请求,能够及时获取返回值,但这样我们就必须自己另起一个新的线程来执行。
像如下代码一样,请求参数已经初始化了,具体参数可以看图灵机器人官方文档,很详细:
new Thread() {
@Override
public void run() {
try {
text = new HttpUtils().sendPost("http://tuling123.com/openapi/api", keys, values);
readJSON(text);//解析JSON字符串,获得想要的数据
list.add(new Msg(text, 1));
if (url != null) {
list.add(new Msg(url, 1));
}
} catch (IOException e) {
Log.e("IOException", e.toString());
}
handler.sendEmptyMessage(0);
}
}.start();
public void readJSON(String strJson) {
Log.i("strJson", strJson);
JSONObject jsonObject;
try {
jsonObject = new JSONObject(strJson);
text = jsonObject.getString("text");
url = jsonObject.getString("url");
} catch (JSONException e) {
url = null;
e.printStackTrace();
}
}
获取到机器人返回给我们的答案之后,用handler更新一下我们的聊天界面:
Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
switch(msg.what) {
case 0:
chatAdapter.notifyItemInserted(chatAdapter.getItemCount() - 1);
rvChat.smoothScrollToPosition(chatAdapter.getItemCount() - 1);
break;
}
}
};
好了,简单的智能聊天就讲到这里,感兴趣的可以看下我放在github上的源码,戳这里—>