Socket通信在项目中时有用到,把长连接的相关实例分享一下。

如果要保持一个长连接,Socket代码最好写在一个服务内,避免误杀。

public class SocketService extends Service {

/**

* 心跳标记

*/

private boolean heartFlag = false;

/**

* 是否接受服务器消息

*/

private boolean isReceive = true;

/**

* 线程是否启动

*/

private boolean isStarted;

//初始化Socket

private Socket socket;

//定义一个handler

private Handler mHandler = new Handler(){

public void handleMessage(android.os.Message msg) {

handleMsg(msg);

}

};

/**

* Socket的正常通信数据

*/

public final int HANDLER_MSG_TAG = 0x1001;

/**

* 连接异常handler

*/

public final int EXCEPTION_HANDLER_TAG = 0x1002;

/**

* 主界面提示socket异常,点击可以重新连接

*/

public final int EXCEPTION_SOCKET_TAG=0x1003;

/**

* 定义全局的json

*/

public static String jsonmsg="";

@Override

public IBinder onBind(Intent intent) {

// TODO: Return the communication channel to the service.

throw new UnsupportedOperationException("Not yet implemented");

}

@Override

public void onCreate() {

super.onCreate();

startSocketService();

}

private void startSocketService() {

//判断网络链接的情况下

if (NetUtils.isConnected(getApplicationContext())) {

AcceptThread thread = new AcceptThread();

thread.start();

} else {

sendHandler(EXCEPTION_HANDLER_TAG);

}

}

/**

* Handler 发送消息

*/

public void sendHandler(int tag) {

Message msg = new Message();

msg.what = tag;

mHandler.sendMessage(msg);

}

/**

* 新线程 用于Socket长连接

*/

class AcceptThread extends Thread {

@Override

public void run() {

super.run();

Log.e("%%%%%%%%", "-----------socket线程打开");

if (!isStarted) {

try {

socket = new Socket("IP", 7094); //两个参数,IP和端口号

isStarted = true;

isReceive = true;

heartFlag = true;

socket.setKeepAlive(true);

startMsgLooper(socket);

} catch (UnknownHostException e) {

Log.d("exception",

"断开连接-------UnknownHostException-----%%" + e.getMessage());

} catch (IOException e) {

if (e instanceof SocketException) {

Log.d("exception", "-------SocketException-----%%" + e.getMessage());

}

Log.d("exception",

"断开连接-------IOException-----%%" + e.getMessage());

} catch (Exception e) {

Log.d("exception",

"断开连接-------Exception-----%%" + e.getMessage());

}

}

}

}

/**

* @param client 初始化完成的Socket

* @throws IOException

*/

public void startMsgLooper(Socket client) throws IOException {

String msg = "";

// 这个控制需要你来完成,while中的true

while (isReceive) {

//Socket通过服务器返回的消息

msg = receiveMsg(client);

if (msg != null) {

//首次返回,确认连接成功

if ("{\"state\":200,\"type\":\"confirm\"}".equals(msg)) {

// String为需要传入发送给服务的数据

sendMsg("String", client);

LogUtil.e("asker----",msg); //首次心跳返回

startHeartBeatThread(client);

} else if ("heartbeat".equals(msg)) {

// 在没有数据返回时,持续返回心跳

Log.e("%%%------","heartbeat");

} else {

//Hander机制把数据传出来

Message message = new Message();

message.what = HANDLER_MSG_TAG;

Bundle bundle = new Bundle();

bundle.putString("msg", msg);

message.setData(bundle);

mHandler.sendMessage(message);

}

} else {

//没有接收到心跳时候判断

Log.e("%%%------", "----------我心跳异常,我没收到");

CustomToast.showToast("心跳异常");

}

}

}

/**

* 对socket获取的数据进行读取

* @param in

* @return

* @throws IOException

*/

public static String readLine(PushbackInputStream in) throws IOException {

char buf[] = new char[128];

int room = buf.length;

int offset = 0;

int c;

loop:

while (true) {

switch (c = in.read()) {

case -1:

case '\n':

break loop;

case '\r':

int c2 = in.read();

if ((c2 != '\n') && (c2 != -1)) {

in.unread(c2);

}

break loop;

default:

if (--room < 0) {

char[] lineBuffer = buf;

buf = new char[offset + 128];

room = buf.length - offset - 1;

System.arraycopy(lineBuffer, 0, buf, 0, offset);

}

buf[offset++] = (char) c;

//把截取的heartbeat返回

if (String.copyValueOf(buf, 0, offset).equals("heartbeat")) {

break loop;

}

break;

}

}

if ((c == -1) && (offset == 0))

return null;

return String.copyValueOf(buf, 0, offset);

}

//计时器

private Timer heartBeatTimer;

private TimerTask heartBeatTask;

/**

* 启动心跳线程

*/

private void startHeartBeatThread(final Socket client) {

heartBeatTimer = new Timer();

heartBeatTask = new TimerTask() {

@Override

public void run() {

// Log.e("%%%heart", "心跳----------------" + heartFlag); 心跳日志

try {

if (socket != null && heartFlag) {

sendMsg("heartbeat", client);

}

} catch (IOException e) {

Message message = new Message();

message.what = EXCEPTION_SOCKET_TAG;

mHandler.sendMessage(message);

Log.d("exception", "断开连接-------startHeartBeatThread-----%%"

+ e.getMessage());

} catch (Exception e) {

Message message = new Message();

message.what = EXCEPTION_SOCKET_TAG;

mHandler.sendMessage(message);

Log.d("exception",

"断开连接---startHeartBeatThread----Exception-----%%"

+ e.getMessage());

}

}

};

heartBeatTimer.schedule(heartBeatTask, 1000, 5000);

}

/**

* 发送msg的IO流

* @param string

* @param client

* @throws IOException

*/

private void sendMsg(String string, Socket client) throws IOException {

OutputStream outputStream = client.getOutputStream();

outputStream.write(string.getBytes());

outputStream.flush();

}

/**

* 接受msg的IO流

* @param client

* @return

* @throws IOException

*/

private String receiveMsg(Socket client) throws IOException {

InputStream inputStream = client.getInputStream();

PushbackInputStream pushbackInputStream = new PushbackInputStream(

inputStream);

return readLine(pushbackInputStream);

}

/**

* 处理handler发送的异常情况

* @param msg

*/

public void handleMsg(Message msg) {

switch (msg.what) {

//socket 正常的通信数据,通过广播发送到需要数据的地方

case HANDLER_MSG_TAG:

jsonmsg = msg.getData().getString("msg");

Intent intent = new Intent();

intent.setAction("jsonmsg");

sendBroadcast(intent);

break;

/**

* socket异常时的处理

*/

case EXCEPTION_SOCKET_TAG:

stopSocketService();

// startSocketServer();

// showToast("连接已断开");

break;

default:

break;

}

}

@Override

public void onDestroy() {

stopSocketService();

super.onDestroy();

}

/**

* 关闭socket,2016年1月4日 hgb

*/

public void stopSocketService() {

Log.e("%%%%%%%%", "-----------socket线程被关闭");

isStarted = false;

isReceive = false;

heartFlag = false;

if (heartBeatTask != null) {

heartBeatTask.cancel();

}

if (heartBeatTimer != null) {

heartBeatTimer.cancel();

}

try {

if (socket != null) {

socket.close();

socket = null;

Log.e("%%%%%%%%", "-----------socket.close");

}

} catch (IOException e) {

e.printStackTrace();

}

}

}开启服务:

intentSocket = new Intent(this, SocketService.class);

this.startService(intentSocket);

关闭服务:

this.stopService(intentSocket);

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐