Android之okhttp实现socket通讯(非原创)
文章大纲
一、okhttp基础介绍
二、socket通讯代码实战
三、项目源码下载
四、参考文章

一、okhttp基础介绍
https://www.jianshu.com/p/e3291b7808e7
二、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
四、参考文章
Android之okhttp实现socket通讯(非原创)的更多相关文章
- android wifi 热点、socket通讯
WiFi管理工具类 package com.wyf.app.common; import java.lang.reflect.InvocationTargetException; import jav ...
- Android SQLite API的使用(非原创)
1.使用SQLite的API来进行数据库的添加.删除.修改.查询 package com.example.sqlitedatabase.test; import android.content.Con ...
- Android SQLite的使用1(非原创)
1.继承SQLiteOpenHelper :public class MyOpenHelper extends SQLiteOpenHelper {} 2.重写下面3个方法 package com.e ...
- Android SQLite的使用2(非原创)
1.数据库的增.删.改.查:execSQL方法 public void insertAction() {//添加信息 db.execSQL("insert into Emp(name,sal ...
- android开发系列之socket编程
上周在项目遇到一个接口需求就是通讯系列必须是socket,所以在这篇博客里面我想谈谈自己在socket编程的时候遇到的一些问题. 其实在android里面实现一个socket通讯是非常简单的,我们只需 ...
- Protobuf实现Android Socket通讯开发教程
本节为您介绍Protobuf实现Android Socket通讯开发教程,因此,我们需要先了理一下protobuf 是什么? Protocol buffers是一种编码方法构造的一种有效而可扩展的格式 ...
- Android笔记:Socket通讯常见问题
经验证的socket通讯问题 1.如果是模拟器和本机PC直接通讯,需要使用本机IP地址 而不是 10.0.2.2 如本机的静态地址为192.168.1.2 则直接使用该地址 2.接收和连接代码不能在 ...
- Delphi 跨平台 Socket 通讯库
Delphi 跨平台 Socket 通讯库 免费开源的Delphi 跨平台 Socket 通讯库. 源码URL:https://github.com/winddriver/Delphi-Cross-S ...
- 利用BlazeDS的AMF3数据封装与Flash 进行Socket通讯
前几天看到了Adobe有个开源项目BlazeDS,里面提供了Java封装AMF3格式的方法.这个项目貌似主要是利用Flex来Remoting的,不过我们可以利用他来与Flash中的Socket通讯. ...
随机推荐
- 怎样使用element-starter快速搭建ElementUI项目
场景 为了能快速搭建起一个ElementUI项目,我们可以使用element-starter这个模板进行快速搭建. element-starter的Github https://github.com/ ...
- 微信小程序 wxml 文件中如何让多余文本省略号显示?
废话不多说,之前写小程序碰到了一个问题,如何在 wxml 页面中截取数据? 1.wxs 取数据想必大家都会,不就是 substring 吗?但是这种方法在 wxml 页面中是无效的. 那还有 cs ...
- [PHP] stream_set_blocking非阻塞模式影响fgets fread函数
当设置socket为非阻塞时,fread或者fgets函数会立即返回结果,而不需要等待有输入,测试过程可以使用vscode的debug模式来进行当不设置这一项时,如果客户端没有输入会一直阻塞在这里等待 ...
- golang中的定向通道(Directional channels)
好像第一次看到这个知识点,作个记录. 注意通道在只能发射或只能接收信息时,<-这个符号放置的位置. package main import "fmt" import &quo ...
- 微信小程序支付功能讲解(1)
前言:虽然小程序做过很多,但是一直觉得微信支付功能很是神秘,现在终于有机会接触心里还是有点小激动的,经过一番折腾发现支付也不过如此,在此记录下支付功能的实现过程 小程序的官方文档介绍到发起微信支付即调 ...
- AcWing 13. 找出数组中重复的数字
习题地址 https://www.acwing.com/solution/acwing/content/2919/. 题目描述给定一个长度为 n 的整数数组 nums,数组中所有的数字都在 0∼n−1 ...
- Windows下同时安装python2和python3如何兼容版本
引言:因学习需要把python2和python3都安装了,为了避免使用过程中混淆版本在网上找了一些解决方案,亲测可用.方法如下: 分别下载并安装Python2.x和Python3.x. 配置环境变量. ...
- vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...
- iOS: 创建静态库,实现自己的API私有使用
一.介绍 在开发中经常使用到第三方的静态框架,格式基本上就是.framework和.a格式的.使用时,会发现我们只能使用无法修改,这就是静态框架的一个好处,私有性.内部实现的代码只有公开者本人知晓,对 ...
- css top,right,bottom,left设置为0有什么用?它和width:100%和height:100%有什么区别?
壹 ❀ 引 当我们使用position属性时,总免不了与top,left,right,bottom四个属性打交道,那么这四个属性都设置为0时有什么用,与宽高设置100%又有什么区别?本文对此展开讨论 ...