android tcp 长连接
2016-01-21 14:22
363 查看
package com.dingmore.terminal.socket; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; import java.net.Socket; import java.net.UnknownHostException; import java.util.Arrays; import android.app.Service; import android.content.Intent; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.support.v4.content.LocalBroadcastManager; import android.util.Log; public class SocketService extends Service { private static final String TAG = "BackService"; private static final long HEART_BEAT_RATE = 30 * 1000; public static final String HOST = "203.195.143.58";// "192.168.1.21";// public static final int PORT = 51001; public static final String MESSAGE_ACTION="com.dingmore.terminal.socket"; public static final String HEART_BEAT_ACTION="com.dingmore.terminal.socket.heart"; public static final String HEART_BEAT_STRING="00";//心跳包内容 private ReadThread mReadThread; private LocalBroadcastManager mLocalBroadcastManager; private WeakReference<Socket> mSocket; // For heart Beat private Handler mHandler = new Handler(); private Runnable heartBeatRunnable = new Runnable() { @Override public void run() { if (System.currentTimeMillis() - sendTime >= HEART_BEAT_RATE) { boolean isSuccess = sendMsg(HEART_BEAT_STRING);//就发送一个HEART_BEAT_STRING过去 如果发送失败,就重新初始化一个socket if (!isSuccess) { mHandler.removeCallbacks(heartBeatRunnable); mReadThread.release(); releaseLastSocket(mSocket); new InitSocketThread().start(); } } mHandler.postDelayed(this, HEART_BEAT_RATE); } }; private long sendTime = 0L; private IBackService.Stub iBackService = new IBackService.Stub() { @Override public boolean sendMessage(String message) throws RemoteException { return sendMsg(message); } }; @Override public IBinder onBind(Intent arg0) { return iBackService; } @Override public void onCreate() { super.onCreate(); new InitSocketThread().start(); mLocalBroadcastManager=LocalBroadcastManager.getInstance(this); } public boolean sendMsg(String msg) { if (null == mSocket || null == mSocket.get()) { return false; } Socket soc = mSocket.get(); try { if (!soc.isClosed() && !soc.isOutputShutdown()) { OutputStream os = soc.getOutputStream(); String message = msg; os.write(message.getBytes()); os.flush(); sendTime = System.currentTimeMillis();//每次发送成数据,就改一下最后成功发送的时间,节省心跳间隔时间 } else { return false; } } catch (IOException e) { e.printStackTrace(); return false; } return true; } private void initSocket() {//初始化Socket try { Socket so = new Socket(HOST, PORT); mSocket = new WeakReference<Socket>(so); mReadThread = new ReadThread(so); mReadThread.start(); mHandler.postDelayed(heartBeatRunnable, HEART_BEAT_RATE);//初始化成功后,就准备发送心跳包 } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void releaseLastSocket(WeakReference<Socket> mSocket) { try { if (null != mSocket) { Socket sk = mSocket.get(); if (!sk.isClosed()) { sk.close(); } sk = null; mSocket = null; } } catch (IOException e) { e.printStackTrace(); } } class InitSocketThread extends Thread { @Override public void run() { super.run(); initSocket(); } } // Thread to read content from Socket class ReadThread extends Thread { private WeakReference<Socket> mWeakSocket; private boolean isStart = true; public ReadThread(Socket socket) { mWeakSocket = new WeakReference<Socket>(socket); } public void release() { isStart = false; releaseLastSocket(mWeakSocket); } @Override public void run() { super.run(); Socket socket = mWeakSocket.get(); if (null != socket) { try { InputStream is = socket.getInputStream(); byte[] buffer = new byte[1024 * 4]; int length = 0; while (!socket.isClosed() && !socket.isInputShutdown() && isStart && ((length = is.read(buffer)) != -1)) { if (length > 0) { String message = new String(Arrays.copyOf(buffer, length)).trim(); Log.e(TAG, message); //收到服务器过来的消息,就通过Broadcast发送出去 if(message.equals(HEART_BEAT_STRING)){//处理心跳回复 Intent intent=new Intent(HEART_BEAT_ACTION); mLocalBroadcastManager.sendBroadcast(intent); }else{ //其他消息回复 Intent intent=new Intent(MESSAGE_ACTION); intent.putExtra("message", message); mLocalBroadcastManager.sendBroadcast(intent); } } } } catch (IOException e) { e.printStackTrace(); } } } } }
IBackService.aidl文件
package com.dingmore.terminal.socket; interface IBackService{ boolean sendMessage(String message); }
具体使用如下
记得在manifest中注册service
//socket start @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); mLocalBroadcastManager.registerReceiver(mReciver, mIntentFilter); bindService(mServiceIntent, conn, BIND_AUTO_CREATE); } @Override protected void onStop() { // TODO Auto-generated method stub unbindService(conn); mLocalBroadcastManager.unregisterReceiver(mReciver); super.onStop(); } private MessageBackReciver mReciver; private IntentFilter mIntentFilter; private Intent mServiceIntent; private LocalBroadcastManager mLocalBroadcastManager; private IBackService iBackService; private ServiceConnection conn = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { iBackService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { iBackService = IBackService.Stub.asInterface(service); } }; private void initSocket() { mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); mReciver = new MessageBackReciver(); mServiceIntent = new Intent(this, SocketService.class); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(SocketService.HEART_BEAT_ACTION); mIntentFilter.addAction(SocketService.MESSAGE_ACTION); } class MessageBackReciver extends Broadc 4000 astReceiver { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(SocketService.HEART_BEAT_ACTION)) { Toast.makeText(Main2Activity.this, "Get a heart heat", Toast.LENGTH_SHORT).show(); } else { String message = intent.getStringExtra("message"); Toast.makeText(Main2Activity.this, message, Toast.LENGTH_SHORT).show(); } }; } //socket end
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- Android IPC进程间通讯机制
- Android Manifest 用法
- [转载]Activity中ConfigChanges属性的用法
- Android之获取手机上的图片和视频缩略图thumbnails
- Android之使用Http协议实现文件上传功能
- Android学习笔记(二九):嵌入浏览器
- android string.xml文件中的整型和string型代替
- i-jetty环境搭配与编译
- android之定时器AlarmManager
- android wifi 无线调试
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- android 代码实现控件之间的间距
- android FragmentPagerAdapter的“标准”配置
- Android"解决"onTouch和onClick的冲突问题
- android:installLocation简析
- android searchView的关闭事件
- SourceProvider.getJniDirectories