喻志强的博客
耐心 细心 用心 传播正能量
Android Socket连接(模拟心跳包,断线重连,发送数据等)
这两天做了一个项目是app通过socket连接自动炒菜机,给炒菜机发指令,炒菜机接收到指令会执行相应的操作。(程序虽然做的差不多了,然而我连炒菜机长什么样都没见过)
其实作为一个会做饭的程序猿,我坚信还是自己动手做的饭菜比较好吃,毕竟做饭还是很有趣的。
闲话不多说,因为是通过socket去连接炒菜机的,并且要求每两秒要给炒菜机发送一个指令,点击按钮的话也要发送相应的指令。
因为是要保证全局只能有一个连接,而且我们还需要在不同的Activity中发指令,因此肯定不能在需要发指令的界面中都去连接socket,这样一来不好管理,性能也不好,重复代码也会比较多,所以想了一下还是把socket放到service中比较好,发指令功能都放在service中即可。
记得要先给网络权限
1
2
<uses-permission android:name="android.permission.INTERNET" />
- 1
下面我们来看看Service中的代码,其中有些细节是需要注意的
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
package com.yzq.socketdemo.service;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.util.Log;
import android.widget.TabHost;
import android.widget.Toast;
import com.yzq.socketdemo.common.Constants;
import com.yzq.socketdemo.common.EventMsg;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import java.io.OutputStream;
import java.net.ConnectException;
import java.net.InetSocketAddress;
import java.net.NoRouteToHostException;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by yzq on 2017/9/26.
* <p>
* socket连接服务
*/
public class SocketService extends Service {
/*socket*/
private Socket socket;
/*连接线程*/
private Thread connectThread;
private Timer timer = new Timer();
private OutputStream outputStream;
private SocketBinder sockerBinder = new SocketBinder();
private String ip;
private String port;
private TimerTask task;
/*默认重连*/
private boolean isReConnect = true;
private Handler handler = new Handler(Looper.getMainLooper());
@Override
public IBinder onBind(Intent intent) {
return sockerBinder;
}
public class SocketBinder extends Binder {
/*返回SocketService 在需要的地方可以通过ServiceConnection获取到SocketService
*/
public SocketService getService() {
return SocketService.this;
}
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
/*拿到传递过来的ip和端口号*/
ip = intent.getStringExtra(Constants.INTENT_IP);
port = intent.getStringExtra(Constants.INTENT_PORT);
/*初始化socket*/
initSocket();
return super.onStartCommand(intent, flags, startId);
}
/*初始化socket*/
private void initSocket() {
if (socket == null && connectThread == null) {
connectThread = new Thread(new Runnable() {
@Override
public void run() {
socket = new Socket();
try {
/*超时时间为2秒*/
socket.connect(new InetSocketAddress(ip, Integer.valueOf(port)), 2000);
/*连接成功的话
发送心跳包*/
if (socket.isConnected()) {
/*因为Toast是要运行在主线程的
这里是子线程
所以需要到主线程哪里去显示toast*/
toastMsg("socket已连接");
/*发送连接成功的消息*/
EventMsg msg = new EventMsg();
msg.setTag(Constants.CONNET_SUCCESS);
EventBus.getDefault().post(msg);
/*发送心跳数据*/
sendBeatData();
}
} catch (IOException e) {
e.printStackTrace();
if (e instanceof SocketTimeoutException) {
toastMsg("连接超时,正在重连");
releaseSocket();
} else if (e instanceof NoRouteToHostException) {
toastMsg("该地址不存在,请检查");
stopSelf();
} else if (e instanceof ConnectException) {
toastMsg("连接异常或被拒绝,请检查");
stopSelf();
}
}
}
});
/*启动连接线程*/
connectThread.start();
}
}
/*因为Toast是要运行在主线程的
所以需要到主线程哪里去显示toast*/
private void toastMsg(final String msg) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
}
});
}
/*发送数据*/
public void sendOrder(final String order) {
if (socket != null && socket.isConnected()) {
/*发送指令*/
new Thread(new Runnable() {
@Override
public void run() {
try {
outputStream = socket.getOutputStream();
if (outputStream != null) {
outputStream.write((order).getBytes("gbk"));
outputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
} else {
toastMsg("socket连接错误,请重试");
}
}
/*定时发送数据*/
private void sendBeatData() {
if (timer == null) {
timer = new Timer();
}
if (task == null) {
task = new TimerTask() {
@Override
public void run() {
try {
outputStream = socket.getOutputStream();
/*这里的编码方式根据你的需求去改*/
outputStream.write(("test").getBytes("gbk"));
outputStream.flush();
} catch (Exception e) {
/*发送失败说明socket断开了或者出现了其他错误*/
toastMsg("连接断开,正在重连");
/*重连*/
releaseSocket();
e.printStackTrace();
}
}
};
}
timer.schedule(task, 0, 2000);
}
/*释放资源*/
private void releaseSocket() {
if (task != null) {
task.cancel();
task = null;
}
if (timer != null) {
timer.purge();
timer.cancel();
timer = null;
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
outputStream = null;
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
}
socket = null;
}
if (connectThread != null) {
connectThread = null;
}
/*重新初始化socket*/
if (isReConnect) {
initSocket();
}
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i("SocketService", "onDestroy");
isReConnect = false;
releaseSocket();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
好了,连接的service我们基本就做好了,先来看看效果,调试工具使用的是一个网络调试助手,免去我们写服务端的代码。
可以看到,断线重连,连接成功自动发送数据,连接成功发消息这些都有了,实际上数据发送失败重连也是有的,不过模拟器上间隔时间很长,不知道怎么回事,真机没有问题。
解决了service下面就是Activity于service通信的问题了。这个就简单了,我们在service中提供了一个binder,我们可以通过binder来拿到service,然后调service的sendOrder()即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.yzq.socketdemo.activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.AppCompatActivity;
import android.widget.Button;
import android.widget.EditText;
import com.yzq.socketdemo.R;
import com.yzq.socketdemo.service.SocketService;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* Created by yzq on 2017/9/26.
* <p>
* mainActivity
*/
public class MainActivity extends AppCompatActivity {
@BindView(R.id.contentEt)
EditText contentEt;
@BindView(R.id.sendBtn)
Button sendBtn;
private ServiceConnection sc;
public SocketService socketService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindSocketService();
ButterKnife.bind(this);
}
private void bindSocketService() {
/*通过binder拿到service*/
sc = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
SocketService.SocketBinder binder = (SocketService.SocketBinder) iBinder;
socketService = binder.getService();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
Intent intent = new Intent(getApplicationContext(), SocketService.class);
bindService(intent, sc, BIND_AUTO_CREATE);
}
@OnClick(R.id.sendBtn)
public void onViewClicked() {
String data = contentEt.getText().toString().trim();
socketService.sendOrder(data);
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(sc);
Intent intent = new Intent(getApplicationContext(), SocketService.class);
stopService(intent);
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
ok,大功告成
-
暴躁的码字猴 2018-02-28 15:46:37 #3楼请问 你家炒菜机上市没,我去买一个
-
伤不起12 2017-12-07 10:39:57 #2楼能默默的问一个,怎么接收数据吗,我将inputstream用eventbus传到main界面,因为不停接收,会出现oom的查看回复(1)
-
wwwzwb 2017-10-15 22:45:13 #1楼不错,图文并茂还有源码,再看不明白就只能去工地搬砖了!
- 上一页
- 1
- 下一页
【android学习】断线重连机制
【解决问题】 android端连接网络之后,当网络断开连接时,为了提高用户体验,android自动检测网络,当有网络时,用户无需进行多余操作,android端自动重新连接网络。 【解决方案】 1...
SunshineTan
2016-07-27 22:41:07
阅读数:7034
关于socket判断连接断开并重连
关于socket判断连接断开并重连 以下是个线程函数 UINT CMonitorDlg::ThreadFunction(LPVOID pParam) { WSADATA wsaData; SOCKET...
tengxiaoming
2010-08-27 01:02:00
阅读数:8423
android-socket斷開之後重新連接 - CSDN博客
最后,将SocketClient.resetSocket();放入图片中的catch{}中,捕获异常的时候重新...Websocket SSL加密之android端(带重连) 最近在开发Android手机端的websocket通信...
2018-5-25
WebSocket安卓客户端实现详解(一)--连接建立与重连 - CSDN博客
WebSocket安卓客户端实现详解(一)–连接建立与重连 今年在公司第一个需求就是...android中使用webSocket通信 概述最近公司项目准备使用WebSocket实现消息推送功能,在...
2018-3-2
WebSocket安卓客户端实现详解(一)--连接建立与重连
今年在公司第一个需求就是基于websocket写一个客户端消息中心,现在已经上线很久了在司机这种网络环境平均一天重连8次,自认为还是不错的.当时写的时候那个心酸啊,主要因为第一次写都不知道该从哪下手,...
zly921112
2017-06-10 00:07:03
阅读数:19672
Android:这是一份很详细的Socket使用攻略 - CSDN博客
前言Socket的使用在Android的网络编程中非常重要今天我将带大家全面了解Socket及其使用方法 目录1.网络基础1.1 计算机网络分层计算机网络分为五层:物理层、数据链路层...
2018-5-2
android端 socket长连接 架构 - CSDN博客
看过包建强的《App研发录》之后对其中的基础Activity类封装感到惊讶,一直想找一种方式去解决关于app中使用socket长连接问题,如何实现简易的封装来达到主活动中涉及...
2018-5-28
Android Socket连接(心跳检测,断线重连,状态监测等)
2017年09月27日 13.06MB 下载
android-socket斷開之後重新連接
今天研究这个问题搞了整整一天啊!终于出来了,不过我没有多大的成就感,为什么呢?因为这是我学长的劳动成果。同样的问题,我却没想出来!心塞的很啊…… 不过还是要给大家分享一下,希望给大家带来帮助! ...
yqj234
2016-04-27 10:24:49
阅读数:405
问题:解决Android中socket自动断开连接 - 酸豆角作坊 - CSDN博客
后来查找了资料,显示原来Android中蓝牙socket通信连接时长大概为120s,如果超过这个...• Android入门实战 • socket连接,判断连接中断,如果中断,并自动重连。 ...
2017-9-19
Android:这是一份很详细的Socket使用攻略 - CSDN博客
Socket的使用在 Android网络编程中非常重要 今天我将带大家全面了解 Socket及 其...Android:RxJava 结合 Retrofit 全面实现 网络请求出错重连 Android:RxJava 结合...
2017-12-27
Socket长连接Android端心跳机制实现
前面用golang写的socket服务端请移步:http://blog.csdn.net/u010072711/article/details/760821761. 把socket链接和心跳功能都放在...
u010072711
2017-07-25 22:36:27
阅读数:7978
Android中Socket使用 - CSDN博客
Android Socket用法详解 2015-11-08 16:51 73人阅读 评论(0) 收藏 举报 分类: android基础(28) 在客户/服务器通信模式中, 客户端需要...
2018-4-19
Android:最全面的Socket使用解析 - CSDN博客
版权声明:本文为博主原创文章,未经博主允许不得转载,更多文章请继续关注Carson_Ho的博客! 目录(?)[+] 前...
2018-5-23
Android-----借助MINA框架实现长连接、短连接以及断线重连
前面我们分析了MINA框架的源码,大家可以从这里进行查看,这篇博客我们使用MINA来完成项目中经常会用到的长连接、短连接、断线重连功能,直接开始了; MINA本身...
hzw19920329
2016-08-13 17:40:31
阅读数:6750
Android中判断socket通信断开
你好!这里是风筝的博客,欢迎和我一起交流。 如果本篇博客对您有帮助,或许可以在下方评论给我留个言呀。 可以引起网络连接关闭的情况有以下4种: 1. 直接调用Socket类的close方法...
Guet_Kite
2017-04-21 19:20:25
阅读数:4411
Android:这是一份很详细的Socket使用攻略 - CSDN博客
最后。该关闭的流和 socket。是一定要关闭的。。。 Socket的使用在 Android网络编程中非常重要 今天我将带大家全面了解 Socket 及 其使用方法 目录 1...
2018-3-7
安卓 java有效判断Socket连接断开和安卓TCP测试APP(客户+服务端一体)
1. 利用socket提供的isConnected()与isClosed()方法来判断。但这种方式只是本地判断,只是本地操作connect()或close()方法后保存的一个状态,对于远程服务器主动断...
HelloMyPeople
2016-07-14 09:51:02
阅读数:5791
问题:解决Android中socket自动断开连接
连接上蓝牙模块后,能够正常读数,蓝牙数据发送速率为0.03s每个。大概在发送了342个数据之后,突然接收不到数据了。...
pursue16
2017-05-14 17:13:32
阅读数:2380
Android socket与服务器通信及心跳连接的实现
在项目中,有如下需求:Android客户端向服务器发送数据,收到服务器返回的数据发送成功标识后,客户端即与服务器建立数据一来一往的心跳连接,若服务器端断开时,客户端接收到通知,关闭Service停止发...
androidforwell
2017-02-14 17:19:48
阅读数:6071
android socket 实现心跳包
//开一个新线程 new Thread(){ //用handle处理要发送的数据 Handler handler = new Handler(){ public voi...
mobei1983
2016-05-27 11:01:58
阅读数:594
Android的socket长连接(心跳检测)
2016年03月23日 2.78MB 下载
Android心跳包(一)——心跳实现
长连接 测试服务器: Socket基本上都这么一个流程。 public class Test { private static final int PORT = 1234; ...
github_27263697
2017-11-21 16:35:47
阅读数:441
在Android上面如何使用带有心跳检测的Socket
由于移动设备的网络的复杂性,经常会出现网络断开,如果没有心跳包的检测,客户端只会在需要发送数据的时候才知道自己已经断线,会延误,甚至丢失服务器发送过来的数据。一下简单建立一个带有心跳检测的Socket...
cuishiying
2015-08-12 00:45:53
阅读数:426
android长连接心跳机制
在写之前,我们首先了解一下为什么android维护长连接需要心跳机制,首先我们知道,维护任何一个长连接都需要心跳机制,客户端发送一个心跳给 服务器,服务器给客户端一个心跳应答,这样就形成客户端服务器...
rabbit_in_android
2015-11-30 22:21:32
阅读数:19654
Android-socket的基本使用,发送文字和图片以及心跳
项目需求收集通过Socket向服务器发送图片,之前没搞过,网上搜搜写了下面的例子,勉强解决了需求。为了测试切换着方便,所以方法写的有点碎了。。。 原文地址 http://blog.csdn.net/...
qq_25806863
2017-07-20 15:55:20
阅读数:1611
Android socket通信的长连接与心跳检测
在Android开发中,我们可能需要和服务器保持连接不断开,这时需要用到socket通信的长连接,并且定时发送消息检测是否是连接状态——心跳检测。 我们需要一个客户端和一个服务器端的...
JJ583500596
2017-08-02 17:13:15
阅读数:1234
【Android】Android心跳包详解
在做IM通信时,都会遇到这样一个概念:心跳包。又是一个比较抽象的概念,那么心跳包到底是什么呢? 之前做的机房预定系统里,使用的Socket和服务器通信。长连接测试服务器: Socket基本上都这么...
bless2015
2016-09-27 14:04:08
阅读数:5026
Android socket通信长连接(心跳检测)
2016年06月17日 2.78MB 下载
个人资料
-
原创
- 56
-
粉丝
- 147
-
喜欢
- 195
-
评论
- 244
-
等级:
-
访问:
- 19万+
-
积分:
- 2483
-
排名:
- 1万+
我的个人网站
最新文章
- Android获取SHA1值的详细步骤
- 从天地初开到MVC再到MVP
- rxjava2的相关封装
- Kotlin Unresolved reference: 解决办法
- Kotlin的变量和数据类型
博主专栏
-
从零开始,学习web前端
阅读量: 81096 21 篇 -
Kotlin从入门到放弃java
阅读量: 404 2 篇
归档
- 2018年2月1篇
- 2018年1月3篇
- 2017年12月3篇
- 2017年10月5篇
- 2017年9月5篇
- 2017年8月1篇
- 2017年7月5篇
- 2017年6月3篇
- 2017年5月6篇
- 2017年4月4篇
- 2017年3月7篇
- 2017年2月3篇
- 2017年1月7篇
- 2016年11月1篇
- 2016年10月2篇
- 2016年8月1篇
展开
热门文章
- 超简单集成Android Zxing实现扫一扫二维码
阅读量:24982
- Android 底部导航栏 BottomNavigationBar的简单使用
阅读量:15197
- Android Studio3.x新的依赖方式(implementation、api、compileOnly)
阅读量:12346
- Angular项目目录结构详解
阅读量:12136
- Angular环境搭建
阅读量:10864
2
最后
以上就是斯文往事最近收集整理的关于Android Socket连接(模拟心跳包,断线重连,发送数据等)的全部内容,更多相关Android内容请搜索靠谱客的其他文章。