Android之okhttp实现socket通讯(非原创)
文章大纲
一、okhttp基础介绍
二、socket通讯代码实战
三、项目源码下载
四、参考文章
一、okhttp基础介绍
二、socket通讯代码实战
1. 添加依赖和权限
app的build.gradle下添加okhttp依赖
implementation 'com.squareup.okhttp3:okhttp:3.8.1'
androidmanifest.xml文件添加网络权限
<uses-permission android:name="android.permission.internet" />
2. 添加布局文件
activity_main.xml文件中代码如下:
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <button android:id="@+id/start" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="start" android:textsize="16sp" /> <textview android:id="@+id/text" android:layout_width="match_parent" android:layout_height="wrap_content" /> <button android:id="@+id/start2" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="start2" android:textsize="16sp" /> <textview android:id="@+id/text2" android:layout_width="match_parent" android:layout_height="wrap_content" /> </linearlayout>
3. mainactivity逻辑实现
package aidl_customer.com.wj.http_socket; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.view.view; import android.widget.button; import android.widget.textview; import java.util.concurrent.timeunit; import okhttp3.okhttpclient; import okhttp3.request; import okhttp3.response; import okhttp3.websocket; import okhttp3.websocketlistener; import okio.bytestring; /** * okhttp是3.5以后才添加对websocket的支持 */ public class mainactivity extends appcompatactivity { private button start; private textview text; private button start2; private textview text2; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_main); start = (button) findviewbyid(r.id.start); text = (textview) findviewbyid(r.id.text); start2 = (button) findviewbyid(r.id.start2); text2 = (textview) findviewbyid(r.id.text2); start.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { connect(); } }); start2.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { okhttpclient client = new okhttpclient.builder() .readtimeout(3, timeunit.seconds) .build(); request request = new request.builder() .url("ws://echo.websocket.org") .build(); websocket websocket = client.newwebsocket(request, new websocketlistener() { @override public void onopen(websocket websocket, response response) { super.onopen(websocket, response); } @override public void onmessage(websocket websocket, string text) { super.onmessage(websocket, text); } @override public void onmessage(websocket websocket, bytestring bytes) { super.onmessage(websocket, bytes); } @override public void onclosing(websocket websocket, int code, string reason) { super.onclosing(websocket, code, reason); } @override public void onclosed(websocket websocket, int code, string reason) { super.onclosed(websocket, code, reason); } @override public void onfailure(websocket websocket, throwable t, response response) { super.onfailure(websocket, t, response); } }); } }); } /** *websocket官网就提供了相应url可以测试 */ private void connect() { //建立连接 echowebsocketlistener listener = new echowebsocketlistener(); request request = new request.builder() .url("ws://echo.websocket.org") .build(); okhttpclient client = new okhttpclient(); client.newwebsocket(request, listener); client.dispatcher().executorservice().shutdown(); } /** * 重写了websocketlistener中的几个方法,这几个方法很好理解,是用来异步回调的, * 这里简单说一下:onopen当websocket和远程建立连接时回调;两个onmessage就是接收到消息时回调, * 只是消息内容的类型不同;onclosing是当远程端暗示没有数据交互时回调(即此时准备关闭,但连接还没有关闭); * onclosed就是当连接已经释放的时候被回调;onfailure当然是失败时被回调(包括连接失败,发送失败等)。 * * send用来发送消息;close用来关闭连接 */ private final class echowebsocketlistener extends websocketlistener { @override public void onopen(websocket websocket, response response) { websocket.send("hello world"); websocket.send("welcome"); websocket.send(bytestring.decodehex("adef")); websocket.close(1000, "再见"); } @override public void onmessage(websocket websocket, string text) { output("onmessage: " + text); } @override public void onmessage(websocket websocket, bytestring bytes) { output("onmessage bytestring: " + bytes); } @override public void onclosing(websocket websocket, int code, string reason) { websocket.close(1000, null); output("onclosing: " + code + "/" + reason); } @override public void onclosed(websocket websocket, int code, string reason) { output("onclosed: " + code + "/" + reason); } @override public void onfailure(websocket websocket, throwable t, response response) { output("onfailure: " + t.getmessage()); } } private void output(final string content) { runonuithread(new runnable() { @override public void run() { text.settext(text.gettext().tostring() + content + "\n"); } }); } }
温馨提示:
(1)echowebsocketlistener继承okhttp中的抽象类websocketlistener,重写了几个方法,是用来异步回调的,这里简单说一下:onopen当websocket和远程建立连接时回调;两个onmessage就是接收到消息时回调,只是消息内容的类型不同;onclosing是当远程端暗示没有数据交互时回调(即此时准备关闭,但连接还没有关闭);onclosed就是当连接已经释放的时候被回调;onfailure当然是失败时被回调(包括连接失败,发送失败等)。
(2)send用来发送消息;close用来关闭连接
(3)websocket官网就提供了相应url可以测试,测试地址为:ws://echo.websocket.org
(4)关闭连接方式,okhttp提供两个方法来关闭连接:
1)close websocket.close(0, “bye”);请求服务器优雅地关闭连接然后等待确认。在关闭之前,所有已经在队列中的消息将被传送完毕。 既然涉及到交互,那么socket可能不会立即关闭。如果初始化和关闭连接是和activity的生命周期绑定的(比如onpause/onresume),有一些消息可能是在close被调用之后接收到,所以这需要小心去处理。
2)cancel;cancel更加残忍:它会丢弃所有已经在队列中的消息然后残忍地关闭socket。这样也有优点:不必等待家政(housekeeping)和已在队列中消息的传送。然而,选择cancel还是close取决于使用场景。
4. 项目运行与访问
安装apk后,运行主页面如下:
点击start按钮,出现以下结果
三、项目源码下载
链接:https://pan.baidu.com/s/1t8omzy8wlzr2aki8s2xcwq
提取码:jwzi