開發環境: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