开发环境:Android Studio
库文件下载: implementation ‘com.google.code.gson:gson:2.6.2’
关键知识:Socket的熟练使用 接口回调
整体的思路是 基于socket通信 将操作类型与数据封装在一个实体类中,通过json进行传递
踩坑:
1 socket 通信端口号不能小于1024 (1024以内为系统端口号)
2 添加好gson依赖后在AndroidMainfest文件中加入INTERNET网络访问权限
首先来看看数据传递的基本格式—SocketModule
package base;
/**
* Created by zhongwang on 2018/1/22.
*/
public class SocketModule {
/**
* 操作类型 可以定义一个公共类来存放操作类型数据
*/
private String operateType;
/**
* 需要的数据 (所有的数据包括实体类 字符 布尔 等 封装成json字符串传递)
*/
private String baseModule;
public String getOperateType() {
return operateType;
}
public void setOperateType(String operateType) {
this.operateType = operateType;
}
public String getBaseModule() {
return baseModule;
}
public void setBaseModule(String baseModule) {
this.baseModule = baseModule;
}
}
接下来是服务端工具类—WifiConnectUtil
在初始化WifiConnectUtil后调用startObserver方法传入业务类接口即可
package cn.ml_tech.mx.mlservice.Util;
import android.content.Context;
import android.util.Log;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import cn.ml_tech.mx.mlservice.base.MlServerApplication;
import cn.ml_tech.mx.mlservice.base.SocketModule;
/**
* 创建时间: 2017/12/26
* 创建人: Administrator
* 功能描述:
*/
public class WifiConnectUtil {
private static WifiConnectUtil wifiConnectUtil;
private MlServerApplication mlServerApplication;
private String ipAddress = "";
private ExecutorService threadPool;//线程池
private ServerSocket serverSocket;
private ToastUtil toastUtil;
private Context context;
private PrintWriter printWriter;
private InputStream inputStream;
private Gson gson;
private Operate operate;
public WifiConnectUtil(Context context) {
this.context = context;
mlServerApplication = (MlServerApplication) context.getApplicationContext();
gson = mlServerApplication.getGson();
toastUtil = ToastUtil.getInstance(context);
ipAddress = "192.168.3.135";
threadPool = Executors.newCachedThreadPool();
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
serverSocket = new ServerSocket(8888);
while (true) {
LogUtil.out(LogUtil.Debug, "等待连接");
Socket server = serverSocket.accept();
printWriter = new PrintWriter(server.getOutputStream(), true);//这个自动刷新要注意一下
LogUtil.out(LogUtil.Debug, "链接成功");
printWriter.println(MlConCommonUtil.CONNECTSUCESS);
inputStream = server.getInputStream();
}
} catch (IOException e) {
e.printStackTrace();
LogUtil.out(LogUtil.Debug, "io异常");
}
}
});
}
public InputStream getInputStream() {
return inputStream;
}
public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
}
public static WifiConnectUtil getWifiConnectUtil(Context context) {
if (wifiConnectUtil == null)
wifiConnectUtil = new WifiConnectUtil(context);
return wifiConnectUtil;
}
/**
* 开始检测移动端发出的指令
*
* @param operate
*/
public void startObserver(Operate operate) {
//其实就是子线程while循环+接口回调啦
this.operate = operate;
LogUtil.out(LogUtil.Debug, "startObserver");
new Thread() {
@Override
public void run() {
super.run();
while (true) {
try {
if (inputStream != null) {
if (inputStream.available() != 0) {
//检测流中是否有数据传入
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String res = bufferedReader.readLine();
LogUtil.out(LogUtil.Debug, res);
SocketModule socketModule = gson.fromJson(res, SocketModule.class);//解析json
handlerOperate(socketModule);//处理数据
}
}
} catch (IOException e) {
e.printStackTrace();
LogUtil.out(LogUtil.Debug, "startObserver IOException");
}
}
}
}.start();
}
/**
* 处理操作类型
*
* @param socketModule
*/
private void handlerOperate(SocketModule socketModule) {
String operateType = socketModule.getOperateType();//获取操作类型
Object operateResult = null;
switch (operateType) {//switch判断 响应不同的操作类型
case MlConCommonUtil.LOGIN:
operateResult = operate.login(socketModule);//业务类中逻辑操作获取结果
socketModule.setBaseModule(gson.toJson(operateResult));//将结果填充
}
String res = gson.toJson(socketModule);//整体转换为json字符串
LogUtil.out(LogUtil.Debug,"获取数据完成,响应移动端进行中");
printWriter.println(res);
LogUtil.out(LogUtil.Debug,"数据发送完成");
}
/**
* 接口回掉
*/
public interface Operate {
Object login(SocketModule socketModule);
}
}
再来就是客户端了
package util;
import android.os.Handler;
import android.util.Log;
import com.google.gson.Gson;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import base.MlApplication;
import base.SocketModule;
/**
* Created by zhongwang on 2018/1/19.
*/
public class MlConnectUtil {
/**
* 端口号 默认888可以通关get set方法修改
*/
private int port = 8888;
/**
* 与电机之间通信 获取数据
*/
private BufferedReader bufferedReader;
/**
* 与电机之间通信 发送指令
*/
private PrintWriter printWriter;
private InputStream inputStream;
private ExecutorService threadPool;
private MlApplication mlApplication;
private static MlConnectUtil mlConnectUtil;
private Handler handler;
private Gson gson;
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public MlConnectUtil(MlApplication application) {
mlApplication = application;
gson = mlApplication.getGson();
handler = new Handler();
Log.d("ZWW",mlApplication.isConnected()+" sssss");
}
public static MlConnectUtil getMlConnectUtil(MlApplication application){
if(mlConnectUtil==null)
mlConnectUtil = new MlConnectUtil(application);
return mlConnectUtil;
}
private Socket clientSocket;
public BufferedReader getBufferedReader() {
return bufferedReader;
}
public void setBufferedReader(BufferedReader bufferedReader) {
this.bufferedReader = bufferedReader;
}
public PrintWriter getPrintWriter() {
return printWriter;
}
public void setPrintWriter(PrintWriter printWriter) {
this.printWriter = printWriter;
}
public void getDataFromMotor(final SocketModule socketModule, final OperateData operateData){
Log.d("zww","数据填充完成,准备发送至服务端");
new Thread(){
@Override
public void run() {
super.run();
printWriter.println(mlApplication.getGson().toJson(socketModule));
startObserver(operateData);
}
}.start();
}
private void startObserver(final OperateData operateData) {
try {
while(true){
if(inputStream!=null&inputStream.available()!=0){
String moduleRes= bufferedReader.readLine();
Log.d("zww","接收到来自服务器的响应 内容如下"+moduleRes);
final SocketModule socketModule = gson.fromJson(moduleRes,SocketModule.class);
handler.post(new Runnable() {
@Override
public void run() {
operateData.handlerData(socketModule);
}
});
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 基于socket通信连接电机
*
* @param ipAddress ip地址
*/
public void ConnectServer(final String ipAddress, final MlApplication mlApplication) {
threadPool = Executors.newCachedThreadPool();
threadPool.execute(new Runnable() {
@Override
public void run() {
try {
if (clientSocket != null) {
clientSocket.close();
}
clientSocket = new Socket(ipAddress, port);
Log.d("zww","开始测试连接");
inputStream = clientSocket.getInputStream();
bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
String res = bufferedReader.readLine();
mlApplication.setConnected(res.equals(MlConCommonUtil.CONNECTSUCESS));
if(mlApplication.isConnected()){
printWriter = new PrintWriter(clientSocket.getOutputStream(),true);
}
Log.d("zww",res);
} catch (IOException e) {
e.printStackTrace();
Log.d("zww", "clientSocket Create faulure");
if(printWriter!=null)
printWriter.close();
if(bufferedReader!=null)
try {
bufferedReader.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
});
}
/**
* 定义接口处理数据
*/
public interface OperateData{
void handlerData(SocketModule socketModule);
}
}
有需要的可以看看
github地址:https://github.com/zw21544182/MlMobile