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%又有什么区别?本文对此展开讨论 ...