avatar
SuemorのBlog
  • 首页
  • 文章
  • 归档
  • 更多
    • 友链
    • 关于
    • 友链
关于 >关于友链关于此项目

@2025 - 2026 Suemor

Powered by Marchen
|所谓自由就是可以说二加二等于四的自由

AndroidV5包源码解析

2022 年 4 月 26 日|
2|
0|
编程|
Android

今年智能家居安装与维护中职组省赛还有1个多月就要开始了,作为一名负责Android开发的蒟蒻,来介绍一下刚更新的SmartHomeV5包源码吧~

其实V5包的源码并不难理解,结合代码片段的注释是很好理解的,我先给出我所写好的示例

示例

java
public class MainActivity extends AppCompatActivity { String name,time; double temperature,humidity,illumination; Handler handler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); findView(); } private void findView() { //连接服务器 ControlUtils.setUser("bizideal", "123456", "127.0.0.1"); SocketClient.getInstance().creatConnect(); SocketClient.getInstance().login(new LoginCallback() { @Override public void onEvent(String var1) { runOnUiThread(new Runnable() { @Override public void run() { if (var1.equals(ConstantUtil.Success)) { Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show(); } else if (var1.equals(ConstantUtil.Reconnect)){ Toast.makeText(MainActivity.this, "重新连接", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_SHORT).show(); } } }); } }); new Handler().postDelayed(new Runnable() { @Override public void run() { //单控 ControlUtils.control("WarningLight", "10", ConstantUtil.CmdCode_1, ConstantUtil.Channel_ALL, ConstantUtil.Open); //获取数据 ControlUtils.getData(); ControlUtils.getFaceData(); SocketClient.getInstance().getData(new DataCallback<DeviceBean>() { @SuppressLint("HandlerLeak") @Override public void onResult(DeviceBean deviceBean) { try { if (!TextUtils.isEmpty(deviceBean.getTime())){ time = deviceBean.getTime(); } } catch (Exception e) { e.printStackTrace(); } try { if (!TextUtils.isEmpty(deviceBean.getName())){ name = deviceBean.getName(); } } catch (Exception e) { e.printStackTrace(); } if (deviceBean.getDevice().size() > 0){ for (int i = 0; i < deviceBean.getDevice().size(); i++) { try { if (deviceBean.getDevice().get(i).getBoardId().equals("1")){ if (deviceBean.getDevice().get(i).getSensorType().equals(ConstantUtil.Illumination)){ temperature = Double.parseDouble(deviceBean.getDevice().get(i).getValue()); }else{ humidity = Double.parseDouble(deviceBean.getDevice().get(i).getValue()); } } } catch (NumberFormatException e) { e.printStackTrace(); } try { if (deviceBean.getDevice().get(i).getBoardId().equals("2")){ illumination = Double.parseDouble(deviceBean.getDevice().get(i).getValue()); } } catch (NumberFormatException e) { e.printStackTrace(); } } } } }); } },500); } }

连接服务器代码解析

好了话不多说,我们看看连接服务器的代码

java
//连接服务器 ControlUtils.setUser("bizideal", "123456", "127.0.0.1"); SocketClient.getInstance().creatConnect(); SocketClient.getInstance().login(new LoginCallback() { @Override public void onEvent(String var1) { runOnUiThread(new Runnable() { @Override public void run() { if (var1.equals(ConstantUtil.Success)) { Toast.makeText(MainActivity.this, "连接成功", Toast.LENGTH_SHORT).show(); } else if (var1.equals(ConstantUtil.Reconnect)){ Toast.makeText(MainActivity.this, "重新连接", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(MainActivity.this, "连接失败", Toast.LENGTH_SHORT).show(); } } }); } });

别看这只有几行代码,其实已经执行完V5包里几乎全部的代码了

creatConnect()方法

单例模式的运用

我们进入登录的SocketClient.getInstance().creatConnect();的里面,这里涉及到一个单例模式,实例化唯一的SocketClient对象。

java
//我们调用SocketClient.getInstance().XXXX()的时候这个方法都会被调用,也就是单例模式,用来实例化唯一的SocketClient对象 public static SocketClient getInstance() { if (null == mInstance) { mInstance = new SocketClient(); } return mInstance; }

启动InitSocketThread线程

接着我们看到如下,请仔细观看注释,注意:通过源码我们可以看出,我们写代码每执行SocketClient.getInstance().creatConnect()就会断开一下与服务器的连接,因此请不要把这句话放在Fragment里或者多次执行

java
//如果之前已经连接过服务器,再次调用creatConnect()会断开现有连接再重新连接服务器,因此creatConnect()要谨慎调用 public boolean creatConnect() { //第一次创建则为空,因此会执行InitSocketThread()的线程 if (this.mSocket == null) { //开启连接服务器线程 (new SocketClient.InitSocketThread()).start(); } else { //用来断开与服务器连接。 this.release(); //开启连接服务器线程 (new SocketClient.InitSocketThread()).start(); } return false; }

我们假设初次调用creatConnect()方法,便会开启 (new SocketClient.InitSocketThread()).start()线程,

如下我们进入这个线程,这个线程意义不大,直接调用了SocketClient.this.initSocket()方法

java
//执行initSocket()方法用的 class InitSocketThread extends Thread { InitSocketThread() { } public void run() { super.run(); SocketClient.this.initSocket(); } }

V5包核心initSocket()方法

如下我们进入SocketClient.this.initSocket()方法,这是整个V5包的核心代码,请仔细仔细再仔细阅读注释

java
//V5源码的核心方法!!!! private void initSocket() { try { //创建并实例化socket Socket socket = new Socket(); //连接服务器,ip为我们之前 "ControlUtils.setUser("bizideal", "123456", "127.0.0.1");" 中的"127.0.0.1",端口号是定死的(6006)无法更改 socket.connect(new InetSocketAddress(ip, this.port), 3000); //把已经连接服务器的socket赋值给全局的 mSocket。这里的mSocket和Socket是弱引用,不严谨的说可以直接理解为创建Socket实例对象 this.mSocket = new WeakReference(socket); //把我们的之前 "ControlUtils.setUser("bizideal", "123456", "127.0.0.1");" 中的 "bizideal", "123456" 发送给服务器,可以去看sendData() ControlUtils.getData(); //实例化ReadThread对象,ReadThread的线程是用来获取服务器数据的 this.mReadThread = new SocketClient.ReadThread((Socket)this.mSocket.get()); //启动实例化ReadThread线程,获取服务器数据的 this.mReadThread.start(); //执行心跳包,检测是否掉线 this.mHandler.postDelayed(this.heartBeatRunnable, 10000L); //成功连接服务器则都不为空 if (this.mSocket != null && this.mLoginCallback != null) { //根据ConstantUtil,会Toast连接成功 this.mLoginCallback.onEvent("0"); } } catch (IOException var2) { if (this.mLoginCallback != null) { //根据ConstantUtil,会Toast连接失败,无法连接服务器 this.mLoginCallback.onEvent("1"); } //断开服务器连接 this.disConnect(this.mSocket); } }

上面代码可能比较难理解,不过我们可以把它拆分成3部分

  1. ControlUtils.getData();请求数据

  2. this.mReadThread = new SocketClient.ReadThread((Socket)this.mSocket.get());this.mReadThread.start();接收数据

    1. this.mHandler.postDelayed(this.heartBeatRunnable, 10000L);心跳包检测连接服务器状态
请求数据

进入ControlUtils.getData()里,这里比较简单,就是发送JSON请求给服务器,表明需要得到数据

java
//数据采集 public static boolean getData() { try { JSONObject object = new JSONObject(); object.put("Type", "GetDevicState"); object.put("UserName", mUserName); object.put("Password", mPassword); object.put("CurrentTime", (new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")).format(new Date())); //把JSON请求发送给服务器 SocketClient.getInstance().sendData(object.toString()); } catch (JSONException var1) { var1.printStackTrace(); } return true; }

接着进入SocketClient.getInstance().sendData(object.toString());仔细观看注释,发送数据给服务器其中 msg 是刚刚在ControlUtils中创建的 JSON 数据,最终会将这个数据发送给服务器。另外注意 SocketClient.this.sendTime = System.currentTimeMillis()获取发送数据的时间,在第三部分心跳包检测会用的。OK非常简单,第一部分发送数据就是这个流程。

java
//发送数据给服务器其中 msg 是在ControlUtils中创建的 JSON 数据,这里的boolean返回值后续会用做“心跳包“检测 public boolean sendData(final String msg) { //老规矩检查你是否连接了服务器 if (null != this.mSocket && null != this.mSocket.get()) { //把全局 mSocket 赋值给局部的 soc final Socket soc = (Socket)this.mSocket.get(); try { //老规矩检查你是否连接了服务器 if (!soc.isClosed() && !soc.isOutputShutdown()) { //用流来发送数据,不过多解释 (new Thread(new Runnable() { public void run() { try { //用流来发送数据,不过多解释 PrintWriter DataWrite = new PrintWriter(soc.getOutputStream()); DataWrite.write(msg + "\r\n"); DataWrite.flush(); //isSocket是用来判断是否发送成功的 SocketClient.this.isSocket = true; //sendTime获取发送数据的时间,会在另一个线程使用到,判断连接状态 SocketClient.this.sendTime = System.currentTimeMillis(); } catch (IOException var2) { var2.printStackTrace(); //isSocket是用来判断是否发送成功的 SocketClient.this.isSocket = false; } } })).start(); } else { //isSocket是用来判断是否发送成功的 this.isSocket = false; } } catch (Exception var4) { var4.printStackTrace(); //isSocket是用来判断是否发送成功的 this.isSocket = false; } //isSocket是用来判断是否发送成功的 return this.isSocket; } else { return false; } }
接收数据

我们回到V5包的核心initSocket方法,看到如下代码,其中ReadThread就是用来接收数据的

java
//实例化ReadThread对象,ReadThread的线程是用来获取服务器数据的 this.mReadThread = new SocketClient.ReadThread((Socket)this.mSocket.get()); //启动实例化ReadThread线程,获取服务器数据的 this.mReadThread.start();

进入上方ReadThread这个线程,仔细观看注释,这个线程往往使用来响应刚才的请求数据,用来读取服务器发送给我们的数据,会得到一串服务器响应给我们的JSON数据,最后交给SocketClient.this.setData(obj)解析,最终赋值到DeviceBean这个类中,供我们直接使用。

java
//获取服务器数据 private class ReadThread extends Thread { //弱引用局部Socket private WeakReference<Socket> mWeakSocket; private boolean isStart = true; public ReadThread(Socket socket) { //转移全局Socket this.mWeakSocket = new WeakReference(socket); } //断开服务器连接 public void release() { this.isStart = false; //断开服务器连接 SocketClient.this.disConnect(this.mWeakSocket); } //获取服务器数据 public void run() { super.run(); //梅开n度,把局部的mWeakSocket转移给线程内的socket Socket socket = (Socket)this.mWeakSocket.get(); //判空 if (socket != null) { try { String response = ""; //读取服务器数据 BufferedReader DataRead = new BufferedReader(new InputStreamReader(socket.getInputStream())); //判空 while(!socket.isClosed() && this.isStart && !socket.isInputShutdown()) { //判空 while((response = DataRead.readLine()) != null) { //获取服务器返回的JSON数据 JSONObject obj = new JSONObject(response); //解析服务器JSON数据 SocketClient.this.setData(obj); } } } catch (JSONException var5) { var5.printStackTrace(); } catch (Exception var6) { //未知异常就断开服务器连接 this.isStart = false; SocketClient.this.mSocket = null; var6.printStackTrace(); } } } }

下方是SocketClient.this.setData(obj)解析我们收到的JSON数据,解析完成后,也就是我们MainActivity最终调用SocketClient.getInstance().getData()的数据

java
//解析服务器返回的JSON数据 public void setData(JSONObject obj) throws JSONException { DeviceBean bean = new DeviceBean(); if (obj.has("Type")) { //判断数据是数据采集还是考勤机或心跳包的 if (!obj.getString("Type").toString().equals("Upload") && !obj.getString("Type").toString().equals("GetDevicState")) { //判断是否为考勤机 if (obj.getString("Type").toString().equals("UploadPersonInfo") || obj.getString("Type").toString().equals("GetCurrentAttendance")) { try { if (obj.has("Name")) { //考勤的姓名 DeviceBean.setName(obj.getString("Name")); } } catch (JSONException var9) { } try { if (obj.has("Time")) { //考勤的日期 DeviceBean.setTime(obj.getString("Time")); } } catch (JSONException var8) { } if (mDataCallback != null) { mDataCallback.onResult(bean); } } } else { //这里是数据采集的JSON解析 try { //具体怎么解析JSON就不说明了 ArrayList<Devices> deviceList = new ArrayList(); JSONArray array = new JSONArray(obj.get("Data").toString()); for(int i = 0; i < array.length(); ++i) { JSONObject jsonObject = array.getJSONObject(i); Devices devices = new Devices(); //数据的值 devices.setValue(jsonObject.getString("Value")); //类型 devices.setSensorType(jsonObject.getString("SensorType")); //版号 devices.setBoardId(jsonObject.getString("BoardId")); deviceList.add(devices); } //解析完的数据放进DeviceBean集合中 DeviceBean.setDevice(deviceList); } catch (JSONException var10) { } //如果写了获取数据的回调,就执行可以拿到数据了 if (mDataCallback != null) { mDataCallback.onResult(bean); } } } else if (obj.has("state") && obj.getString("state").toString().equals("Failure") && obj.has("msg") && this.mLoginCallback != null) { //未知错误 this.mLoginCallback.onEvent("5"); } }
心跳包检测

我们回到V5包的核心initSocket方法,看到如下代码,这里开启heartBeatRunnable用于心跳包检测,当你超过10秒钟没有发送数据给服务器便会执行,应用服务器心跳检测,简称“心跳包”,检测你是否掉线,其中SocketClient.this.sendTime就是第一部分,请求数据接收的时间

java
//执行心跳包,检测是否掉线 this.mHandler.postDelayed(this.heartBeatRunnable, 10000L);
java
//用来开启下方 heartBeatRunnable 线程,详情看initSocket()方法 private Handler mHandler = new Handler(); //配合上方mHandler开启线程 详情看initSocket()方法 //判断你是否掉线 private Runnable heartBeatRunnable = new Runnable() { public void run() { try { //当你超过10秒钟没有发送数据给服务器变会执行,应用服务器心跳检测,简称“心跳包”,检测你是否掉线,SocketClient.this.sendTime就是第一部分,请求数据接收的时间 if (System.currentTimeMillis() - SocketClient.this.sendTime >= 10000L) { //发送心跳包 boolean isSuccess = SocketClient.this.sendData("{\"Type\": \"HeartBeat\"}"); //如果掉线 if (!isSuccess) { //如果你调用了LoginCallback回调,就!=null if (SocketClient.this.mLoginCallback != null) { //根据ConstantUtil的 public static String Reconnect = "2"; 会Toast出“重新连接" SocketClient.this.mLoginCallback.onEvent("2"); } //停止这个heartBeatRunnable线程 SocketClient.this.mHandler.removeCallbacks(SocketClient.this.heartBeatRunnable); //断开服务器连接 SocketClient.this.mReadThread.release(); //重新建立服务器连接 (SocketClient.this.new InitSocketThread()).start(); } } //以每15秒频率重复执行心跳包 SocketClient.this.mHandler.postDelayed(this, 15000L); } catch (Exception var2) { var2.printStackTrace(); } } };
心跳包心跳包

总结&&源码

以上便是V5包源码的全部核心,剩下一部分没有提到的都很好理解,相信可以做到举一反三吧emmmmm,如果有什么不明白的可以发送邮件到1502972236zwj@gmail.com 与我联系,最后附上全部SocketClien类的源码注释。

java
package com.bizideal.smarthome.socket; import android.os.Handler; import com.bizideal.smarthome.socket.DeviceBean.Devices; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.net.InetSocketAddress; import java.net.Socket; import java.util.ArrayList; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; //V5连接服务器核心类 public class SocketClient { //SocketClient(也就是自己)的实例对象 private static SocketClient mInstance; //获取数据回调 private static DataCallback mDataCallback; //创建全局Socket的弱引用,不严谨的说可以直接理解为创建Socket实例对象 private WeakReference<Socket> mSocket; //创建ReadThread对象,ReadThread的线程是用来获取服务器数据的 public SocketClient.ReadThread mReadThread; //每次向服务器发送数据的时间,详情看sendData()方法 private long sendTime = 0L; //ip在 ControlUtils.setUser("bizideal", "123456", "127.0.0.1"); 会对其赋值 public static String ip = "10.1.3.173"; //定死的服务器断开号,无法更改 int port = 6006; //登录回调 private LoginCallback mLoginCallback; //没用 private Boolean isSuccess = false; //用来开启下方 heartBeatRunnable 线程,详情看initSocket()方法 private Handler mHandler = new Handler(); //配合上方mHandler开启线程 详情看initSocket()方法 //判断你是否掉线 private Runnable heartBeatRunnable = new Runnable() { public void run() { try { //当你超过10秒钟没有发送数据给服务器便会执行,应用服务器心跳检测,简称“心跳包”,检测你是否掉线, if (System.currentTimeMillis() - SocketClient.this.sendTime >= 10000L) { //发送心跳包 boolean isSuccess = SocketClient.this.sendData("{\"Type\": \"HeartBeat\"}"); //如果掉线 if (!isSuccess) { //如果你调用了LoginCallback回调,就!=null if (SocketClient.this.mLoginCallback != null) { //根据ConstantUtil的 public static String Reconnect = "2"; 会Toast出“重新连接" SocketClient.this.mLoginCallback.onEvent("2"); } //停止这个heartBeatRunnable线程 SocketClient.this.mHandler.removeCallbacks(SocketClient.this.heartBeatRunnable); //断开服务器连接 SocketClient.this.mReadThread.release(); //重新建立服务器连接 (SocketClient.this.new InitSocketThread()).start(); } } //以每15秒频率重复执行心跳包 SocketClient.this.mHandler.postDelayed(this, 15000L); } catch (Exception var2) { var2.printStackTrace(); } } }; //这是一个 flag 用来判断是否成功发送数据给服务器 private boolean isSocket = false; public SocketClient() { } //我们调用SocketClient.getInstance().XXXX()的时候这个方法都会被调用,也就是单例模式,用来实例化唯一的SocketClient对象 public static SocketClient getInstance() { if (null == mInstance) { mInstance = new SocketClient(); } return mInstance; } public boolean creatConnect() { //第一次创建则为空,因此会执行InitSocketThread()的线程 if (this.mSocket == null) { //开启连接服务器线程 (new SocketClient.InitSocketThread()).start(); } else { //如果之前已经连接过服务器,再次调用creatConnect()会断开现有连接再重新连接服务器,因此creatConnect()要谨慎调用 this.release(); //开启连接服务器线程 (new SocketClient.InitSocketThread()).start(); } return false; } //V5源码的核心方法!!!! private void initSocket() { try { //创建并实例化socket Socket socket = new Socket(); //连接服务器,ip为我们之前 "ControlUtils.setUser("bizideal", "123456", "127.0.0.1");" 中的"127.0.0.1",端口号是定死的(6006)无法更改 socket.connect(new InetSocketAddress(ip, this.port), 3000); //把已经连接服务器的socket赋值给全局的 mSocket this.mSocket = new WeakReference(socket); //把我们的之前 "ControlUtils.setUser("bizideal", "123456", "127.0.0.1");" 中的 "bizideal", "123456" 发送给服务器,可以去看sendData() ControlUtils.getData(); //实例化ReadThread对象,ReadThread的线程是用来获取服务器数据的 this.mReadThread = new SocketClient.ReadThread((Socket)this.mSocket.get()); //启动实例化ReadThread线程,获取服务器数据的 this.mReadThread.start(); //执行心跳包,检测是否掉线 this.mHandler.postDelayed(this.heartBeatRunnable, 10000L); //成功连接服务器则都不为空 if (this.mSocket != null && this.mLoginCallback != null) { //根据ConstantUtil,会Toast连接成功 this.mLoginCallback.onEvent("0"); } } catch (IOException var2) { if (this.mLoginCallback != null) { //根据ConstantUtil,会Toast连接失败,无法连接服务器 this.mLoginCallback.onEvent("1"); } //断开服务器连接 this.disConnect(this.mSocket); } } //发送数据给服务器其中 msg 是在ControlUtils中创建的 JSON 数据,这里的boolean返回值后续会用做“心跳包“检测 public boolean sendData(final String msg) { //老规矩检查你是否连接了服务器 if (null != this.mSocket && null != this.mSocket.get()) { //把全局 mSocket 赋值给局部的 soc final Socket soc = (Socket)this.mSocket.get(); try { //老规矩检查你是否连接了服务器 if (!soc.isClosed() && !soc.isOutputShutdown()) { //用流来发送数据,不过多解释 (new Thread(new Runnable() { public void run() { try { //用流来发送数据,不过多解释 PrintWriter DataWrite = new PrintWriter(soc.getOutputStream()); DataWrite.write(msg + "\r\n"); DataWrite.flush(); //isSocket是用来判断是否发送成功的 SocketClient.this.isSocket = true; //sendTime获取发送数据的时间,会在另一个线程使用到,判断连接状态 SocketClient.this.sendTime = System.currentTimeMillis(); } catch (IOException var2) { var2.printStackTrace(); //isSocket是用来判断是否发送成功的 SocketClient.this.isSocket = false; } } })).start(); } else { //isSocket是用来判断是否发送成功的 this.isSocket = false; } } catch (Exception var4) { var4.printStackTrace(); //isSocket是用来判断是否发送成功的 this.isSocket = false; } //isSocket是用来判断是否发送成功的 return this.isSocket; } else { return false; } } //解析服务器返回的JSON数据 public void setData(JSONObject obj) throws JSONException { DeviceBean bean = new DeviceBean(); if (obj.has("Type")) { //判断数据是数据采集还是考勤机或心跳包的 if (!obj.getString("Type").toString().equals("Upload") && !obj.getString("Type").toString().equals("GetDevicState")) { //判断是否为考勤机 if (obj.getString("Type").toString().equals("UploadPersonInfo") || obj.getString("Type").toString().equals("GetCurrentAttendance")) { try { if (obj.has("Name")) { //考勤的姓名 DeviceBean.setName(obj.getString("Name")); } } catch (JSONException var9) { } try { if (obj.has("Time")) { //考勤的日期 DeviceBean.setTime(obj.getString("Time")); } } catch (JSONException var8) { } if (mDataCallback != null) { mDataCallback.onResult(bean); } } } else { //这里是数据采集的JSON解析 try { //具体怎么解析JSON就不说明了 ArrayList<Devices> deviceList = new ArrayList(); JSONArray array = new JSONArray(obj.get("Data").toString()); for(int i = 0; i < array.length(); ++i) { JSONObject jsonObject = array.getJSONObject(i); Devices devices = new Devices(); //数据的值 devices.setValue(jsonObject.getString("Value")); //类型 devices.setSensorType(jsonObject.getString("SensorType")); //版号 devices.setBoardId(jsonObject.getString("BoardId")); deviceList.add(devices); } //解析完的数据放进DeviceBean集合中 DeviceBean.setDevice(deviceList); } catch (JSONException var10) { } //如果写了获取数据的回调,就执行可以拿到数据了 if (mDataCallback != null) { mDataCallback.onResult(bean); } } } else if (obj.has("state") && obj.getString("state").toString().equals("Failure") && obj.has("msg") && this.mLoginCallback != null) { //未知错误 this.mLoginCallback.onEvent("5"); } } //断开服务器连接 public void disConnect(WeakReference<Socket> mSocket) { try { if (mSocket != null) { Socket sk = (Socket)mSocket.get(); if (!sk.isClosed()) { sk.close(); } sk = null; mSocket = null; } } catch (IOException var3) { var3.printStackTrace(); } } //断开服务器连接 public void release() { try { if (mInstance != null) { mInstance = null; } if (this.mReadThread != null) { this.mReadThread.release(); } if (this.mHandler != null) { this.mHandler.removeCallbacks(this.heartBeatRunnable); } } catch (Exception var2) { } } //连接服务器的LoginCallback赋值给全局mLoginCallback public void login(LoginCallback callback) { this.mLoginCallback = callback; } public void getData(DataCallback callback) { mDataCallback = callback; } //获取服务器数据 private class ReadThread extends Thread { //局部Socket private WeakReference<Socket> mWeakSocket; private boolean isStart = true; public ReadThread(Socket socket) { //转移全局Socket this.mWeakSocket = new WeakReference(socket); } //断开服务器连接 public void release() { this.isStart = false; //断开服务器连接 SocketClient.this.disConnect(this.mWeakSocket); } //获取服务器数据 public void run() { super.run(); //梅开n度,把局部的mWeakSocket转移给线程内的socket Socket socket = (Socket)this.mWeakSocket.get(); //判空 if (socket != null) { try { String response = ""; //读取服务器数据 BufferedReader DataRead = new BufferedReader(new InputStreamReader(socket.getInputStream())); //判空 while(!socket.isClosed() && this.isStart && !socket.isInputShutdown()) { //判空 while((response = DataRead.readLine()) != null) { //获取服务器返回的JSON数据 JSONObject obj = new JSONObject(response); //解析服务器JSON数据 SocketClient.this.setData(obj); } } } catch (JSONException var5) { var5.printStackTrace(); } catch (Exception var6) { //未知异常就断开服务器连接 this.isStart = false; SocketClient.this.mSocket = null; var6.printStackTrace(); } } } } //执行initSocket()方法用的 class InitSocketThread extends Thread { InitSocketThread() { } public void run() { super.run(); SocketClient.this.initSocket(); } } }

目录0%