AndroidV5包源码解析
今年智能家居安装与维护中职组省赛还有1个多月就要开始了,作为一名负责Android开发的蒟蒻,来介绍一下刚更新的SmartHomeV5包源码吧~
其实V5包的源码并不难理解,结合代码片段的注释是很好理解的,我先给出我所写好的示例
示例
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);
}
}
连接服务器代码解析
好了话不多说,我们看看连接服务器的代码
//连接服务器
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对象。
//我们调用SocketClient.getInstance().XXXX()的时候这个方法都会被调用,也就是单例模式,用来实例化唯一的SocketClient对象
public static SocketClient getInstance() {
if (null == mInstance) {
mInstance = new SocketClient();
}
return mInstance;
}
启动InitSocketThread线程
接着我们看到如下,请仔细观看注释
,注意:通过源码我们可以看出,我们写代码每执行SocketClient.getInstance().creatConnect()
就会断开一下与服务器的连接,因此请不要把这句话放在Fragment里或者多次执行
//如果之前已经连接过服务器,再次调用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()
方法
//执行initSocket()方法用的
class InitSocketThread extends Thread {
InitSocketThread() {
}
public void run() {
super.run();
SocketClient.this.initSocket();
}
}
V5包核心initSocket()方法
如下我们进入SocketClient.this.initSocket()
方法,这是整个V5包的核心代码,请仔细仔细再仔细阅读注释
//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部分
ControlUtils.getData();
请求数据this.mReadThread = new SocketClient.ReadThread((Socket)this.mSocket.get());this.mReadThread.start();
接收数据this.mHandler.postDelayed(this.heartBeatRunnable, 10000L);
心跳包检测连接服务器状态
请求数据
进入ControlUtils.getData()
里,这里比较简单,就是发送JSON请求给服务器,表明需要得到数据
//数据采集
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非常简单,第一部分发送数据就是这个流程。
//发送数据给服务器其中 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
就是用来接收数据的
//实例化ReadThread对象,ReadThread的线程是用来获取服务器数据的
this.mReadThread = new SocketClient.ReadThread((Socket)this.mSocket.get());
//启动实例化ReadThread线程,获取服务器数据的
this.mReadThread.start();
进入上方ReadThread
这个线程,仔细观看注释,这个线程往往使用来响应刚才的请求数据,用来读取服务器发送给我们的数据,会得到一串服务器响应给我们的JSON数据,最后交给SocketClient.this.setData(obj)
解析,最终赋值到DeviceBean
这个类中,供我们直接使用。
//获取服务器数据
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()
的数据
//解析服务器返回的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
就是第一部分,请求数据接收的时间
//执行心跳包,检测是否掉线
this.mHandler.postDelayed(this.heartBeatRunnable, 10000L);
//用来开启下方 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
类的源码注释。
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();
}
}
}