小米手机TCP连接一些奇怪现象
2016-03-11 17:26
615 查看
小米手机tcp连接一些奇怪现象
本人写了一个android TCP 客户端一个例子,以TCP&UDP测试工具模拟服务器,每隔一段时间(30S)向手机客户端发送一个字符串。我手上有一台红米note3作为测试机,编译后在手机安装,熄灭屏幕后测试tcp一直处于连接状态。可是我做如下操作会出现一些奇怪的现象(小米机型都出现):如果我将手机重新启动后再打开TcpTest app,熄灭屏幕后,发现这个时候长连接大概只有3分钟的有效时间,测试每次必现。
这个时候如果将AndroidManifest.xml 的包名随意改动下,重新再编译安装,这个时候tcp就又可以一直连接了,但是关机重启后又只能连接两三分钟了。
测试例子下载
以上测试都是app运行后熄灭屏进行的,为了不让app进程被kill掉,请下拉应用将APP锁上 如下图
tcp连接代码 TcpSocket.java
package com.example.tcpsocket; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.util.ArrayList; import java.util.List; import java.util.Vector; import android.util.Log; public class TcpSocket { private DataOutputStream out;// 发送数据流 private DataInputStream in;// 接收数据流 private Socket mSocket;// socket连接对象 private SocketAddress address; private int timeOut = 1000 * 30;// 延迟时间 // 启动一个线程,不停接收服务器数据 private RecThrad recThread;// 接收数据线程 private SendThread sendThread;// 发送线程 private ConnectThread connThread;// private boolean threadBoo = true; private TCPSocketCallback callBack;// 回调接口 private byte[] buffer = new byte[1024 * 1];// 缓冲区字节数组,信息不能大于此缓冲区 private byte[] tmpBuffer;// 临时缓冲区 private static List<byte[]> datas = new ArrayList<byte[]>();// 待发送数据队列 // 构造 public TcpSocket(TCPSocketCallback callback) { // TODO Auto-generated constructor stub this.callBack = callback; } // 开始连接 public void startConnect(String ip, int port) { // 启动连接线程 connThread = new ConnectThread(ip, port); connThread.start(); } // 获取当前连接状态 public boolean getConnectStatus() { if (mSocket != null) return mSocket.isConnected(); else return false; } public void sendData(byte[] data) { if (out != null) { try { out.write(data); out.flush(); } catch (IOException e) { e.printStackTrace(); callBack.disconnect(); } } } public void writeDate(byte[] data) { datas.add(data);// 将发送数据添加到发送队列 } class ConnectThread extends Thread { String ip; int port; public ConnectThread(String ip, int port) { this.ip = ip; this.port = port; } @Override public void run() { super.run(); mSocket = new Socket(); address = new InetSocketAddress(ip, port); try { mSocket.connect(address, timeOut); mSocket.isConnected(); callBack.connected(); out = new DataOutputStream(mSocket.getOutputStream());// 获取网络输出流 in = new DataInputStream(mSocket.getInputStream());// 获取网络输入流 threadBoo = true; //启动接收和发送数据线程 recThread = new RecThrad(); recThread.start(); sendThread = new SendThread(); sendThread.start(); } catch (IOException e1) { e1.printStackTrace(); try { if (out != null) { out.close(); } if (in != null) { in.close(); } if (mSocket != null && !mSocket.isClosed()) {// 判断socket不为空并且是连接状态 mSocket.close();// 关闭socket } } catch (Exception e2) { // TODO: handle exception } if (callBack != null) callBack.disconnect(); } } } /** * 发送线程 */ class SendThread extends Thread { @Override public void run() { super.run(); while (threadBoo) { try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (datas.size() > 0) { byte[] data = datas.remove(0); sendData(data); } } this.close(); } public void close() { threadBoo = false; } } /** * 接收数据线程 关闭资源 打开资源 */ class RecThrad extends Thread { public void run() { super.run(); if (threadBoo) { if (in != null) { int len = 0; try { while ((len = in.read(buffer)) > 0) { tmpBuffer = new byte[len]; System.arraycopy(buffer, 0, tmpBuffer, 0, len); callBack.receive(tmpBuffer); tmpBuffer = null; } } catch (IOException e) { e.printStackTrace(); try { if (out != null) { out.close(); } if (in != null) { in.close(); } if (mSocket != null && !mSocket.isClosed()) {// 判断socket不为空并且是连接状态 mSocket.close();// 关闭socket } } catch (Exception e2) { // TODO: handle exception } if (callBack != null) callBack.disconnect(); } } } } public void close() { threadBoo = false; this.close(); } } // 关闭所有资源 public void close() { threadBoo = false; try { if (mSocket != null) { if (!mSocket.isInputShutdown()) { mSocket.shutdownInput(); } if (!mSocket.isOutputShutdown()) { mSocket.shutdownOutput(); } } if (mSocket != null && !mSocket.isClosed()) {// 判断socket不为空并且是连接状态 mSocket.close();// 关闭socket } if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (Exception e) { e.printStackTrace(); } finally { out = null; in = null; mSocket = null;// 制空socket对象 recThread = null; sendThread = null; connThread = null; callBack = null; } } }
启动tcp代码
void starTcp(){ if(tcp == null){ tcp = new TcpSocket(new TCPSocketCallback() { @Override public void receive(byte[] buffer) { tcp.writeDate(buffer); } @Override public void disconnect() { } @Override public void connected() { } }); tcp.startConnect(ip, port); } }
相关文章推荐
- 使用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