博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在Android上面如何使用带有心跳检测的Socket
阅读量:6342 次
发布时间:2019-06-22

本文共 7849 字,大约阅读时间需要 26 分钟。

hot3.png

    由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测,客户端只会在需要发送数据的时候才知道自己已经断线,会延误,甚至丢失服务器发送过来的数据。一下简单建立一个带有心跳检测的SocketDemo。

Android 后台Servevice

package org.feng.sockettest.server;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 BackService extends Service {	private static final String TAG = "BackService";	private static final long HEART_BEAT_RATE = 3 * 1000;	public static final String HOST = "192.168.1.101";// "192.168.1.21";//	public static final int PORT = 9800;		public static final String MESSAGE_ACTION="org.feng.message_ACTION";	public static final String HEART_BEAT_ACTION="org.feng.heart_beat_ACTION";		private ReadThread mReadThread;	private LocalBroadcastManager mLocalBroadcastManager;	private WeakReference
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("");//就发送一个\r\n过去 如果发送失败,就重新初始化一个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 + "\r\n"; 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
(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
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
mWeakSocket; private boolean isStart = true; public ReadThread(Socket socket) { mWeakSocket = new WeakReference
(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("ok")){//处理心跳回复 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(); } } } }}

在Activity中发送以及接收数据:

package org.feng.sockettest;import java.lang.ref.WeakReference;import org.feng.sockettest.server.BackService;import org.feng.sockettest.server.IBackService;import android.app.Activity;import android.content.BroadcastReceiver;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.IntentFilter;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.os.RemoteException;import android.support.v4.content.LocalBroadcastManager;import android.view.View;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity {	private static final String TAG = "MainActivity";	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 TextView mResultText;	private EditText mEditText;	private Intent mServiceIntent;	class MessageBackReciver extends BroadcastReceiver {		private WeakReference
textView; public MessageBackReciver(TextView tv) { textView = new WeakReference
(tv); } @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); TextView tv = textView.get(); if (action.equals(BackService.HEART_BEAT_ACTION)) { if (null != tv) { tv.setText("Get a heart heat"); } } else { String message = intent.getStringExtra("message"); tv.setText(message); } }; } private MessageBackReciver mReciver; private IntentFilter mIntentFilter; private LocalBroadcastManager mLocalBroadcastManager; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mLocalBroadcastManager = LocalBroadcastManager.getInstance(this); mResultText = (TextView) findViewById(R.id.resule_text); mEditText = (EditText) findViewById(R.id.content_edit); mReciver = new MessageBackReciver(mResultText); mServiceIntent = new Intent(this, BackService.class); mIntentFilter = new IntentFilter(); mIntentFilter.addAction(BackService.HEART_BEAT_ACTION); mIntentFilter.addAction(BackService.MESSAGE_ACTION); } @Override protected void onStart() { super.onStart(); mLocalBroadcastManager.registerReceiver(mReciver, mIntentFilter); bindService(mServiceIntent, conn, BIND_AUTO_CREATE); } @Override protected void onStop() { super.onStop(); unbindService(conn); mLocalBroadcastManager.unregisterReceiver(mReciver); } public void onClick(View view) { switch (view.getId()) { case R.id.send: String content = mEditText.getText().toString(); try { boolean isSend = iBackService.sendMessage(content);//Send Content by socket Toast.makeText(this, isSend ? "success" : "fail", Toast.LENGTH_SHORT).show(); mEditText.setText(""); } catch (RemoteException e) { e.printStackTrace(); } break; default: break; } }}

完整项目带服务器段代码的见:

转载于:https://my.oschina.net/fengcunhan/blog/178155

你可能感兴趣的文章
CopyNet 阅读笔记
查看>>
开发基于以太坊智能合约的DApp
查看>>
要获得“机器学习或数据科学”的工作,到底选哪种编程语言更好?
查看>>
感觉JVM的默认异常处理不够好,既然不好那我们就自己来处理异常呗!那么如何自己处理异常呢?...
查看>>
Java 基础 之 算数运算符
查看>>
OpenAI最新研究:通过无监督学习提高语言理解能力
查看>>
Windows下配置安装Git(二)
查看>>
一个最简单的基于Android SearchView的搜索框
查看>>
Android ToggleButton:状态切换的Button
查看>>
Android ListView Adapter的getItemViewType和getViewTypeCount多种布局
查看>>
CentOS+Nginx+Supervisor部署ASP.NET Core项目
查看>>
uliweb_apijson 0.1.0 发布,自动化接口和文档
查看>>
Windows Server 2008系统如何取消登录时要按Ctrl+Alt+Delete组合键
查看>>
谷歌为 Chrome 推出12款官方新皮肤
查看>>
对话中国AI先锋,生态科技岛首秀深圳
查看>>
Zoho CRM发布2016全新版本:向生态平台演进
查看>>
Android Design Support Library全解:Part 4 TabLayout 实现滑动选项卡
查看>>
Windows下PyMySQL的安装
查看>>
Facebook专为GearVR开发了Facebook 360,可以快速找到最好的VR内容
查看>>
“再得抗量子密术,30000亦不在话下”的hsr会如何抵抗量子攻击?
查看>>