您的位置:首页 > 移动开发 > Android开发

关于android Socket通信中线程阻塞的问题解决(有点乱,随感,有兴趣的可以看看)

2012-09-11 18:56 555 查看
前言:关于android的机制想必大家都了解, 为了避免运行一个时间长的function导致主进程阻塞,android上目前有两个方案供我们选择,一个是Thread .另一个则是Service.

UI主线程运行在Activity里,如需根据子线程的新产生数据改变UI相关的内容,需要在Handler处理,一个线程是独立于主线程的,原理上除非进程被杀死,或者用户自己停止线程,该线程在进程运行过程中一直存在。

如果不需要与用户交互,甚至不需要和进程有交互,则开启一个服务,这样即使进程关闭后台便可以帮我们轻松的处理类似下载,播放的功能。

问题:这次遇到的问题是有关于线程的,

我在这个线程中主要写了和服务器的通信功能,系统运行,和服务器建立连接,然后服务器与客户端进行数据的通信,线程一直接收,判断是否有用户请求,如果有,就发送,没有,循环。

(之前缺乏通信方面的经验,每次发请求,都建立一个连接,获取数据后关闭连接,项目小的时候没发现多大问题,项目大的时候,发现这样效率极低,回想了下网络的知识,这样很不科学额,于是改写了通信功能部分)

我发现我在线程中写的循环只进行了几次就无效了,我原本以为是Activity跳转造成的,但是仔细看了SDK之后发现无关,我很诧异,在测试文件里另外写了一个线程,证明和Activity跳转。大家都知道,由于是线程的错误,调试啥的又 看不出所以然来。我花了不少时间,检查服务器啥的。

最后逐一注释了功能模块(发现注释了红色部分线程不出现阻塞),

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (true) {
Connect();
count++;
Log.v(TAG, "run" + count);
if (Command.size() > 0) {
try {
wtr = new PrintWriter(new OutputStreamWriter(
sk.getOutputStream(), "GBK"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String send = Command.get(0);
Log.v(TAG, "run/command" + send);
if (send != null && send.length() > 0) {
wtr.println(send);
wtr.flush(); // 发送请求
}
//				try {
//					reader = new BufferedReader(new InputStreamReader(
//							sk.getInputStream(), "gbk"));
//					if (reader != null) {
//						String str = reader.readLine();
//						if (str.trim().length() > 0)
//							SortReply.sort(str);
//					}
//				} catch (IOException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
Command.remove(0);
}

try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}
原因分析,一旦服务器端没有数据发送数据给客户端,客户端就会阻塞在那里一直等待,导致线程无法继续循环。

问题找出来了解决办法就简单了,我在这个与服务器进行通信的线程的onCreate函数开启一个接收数据流的线程,然后在它本身复写的run函数中单纯地发送请求,这样保证了一个数据发送不会因为没有收到数据包而阻塞,

改写后如下:

public Client() {
Log.v(TAG, "cLINET");
new getInputStreamThread().start();

}

public static void set_Req(Requests request) {
Command.add(request.Command);
}

private static void Connect() {
if (sk == null) {

try {
sk = new Socket(ipStr, port);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

} else if (!sk.isConnected()) {
try {
sk.connect(new InetSocketAddress(ipStr, port));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.v(TAG, "error:can not connect socket ");
}
}
}

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (true) {
Connect();
count++;
Log.v(TAG, "run" + count);
if (Command.size() > 0) {
try {
wtr = new PrintWriter(new OutputStreamWriter(
sk.getOutputStream(), "GBK"));
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String send = Command.get(0);
Log.v(TAG, "run/command" + send);
if (send != null && send.length() > 0) {
wtr.println(send);
wtr.flush(); // 发送请求
}
Command.remove(0);
}

try {
sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}

public class getInputStreamThread extends Thread {

public int aa = 0;

@Override
public void run() {
// TODO Auto-generated method stub
super.run();
while (true) {
Connect();
aa++;
Log.v("getInputStreamThread", "aa" + aa);
try {
reader = new BufferedReader(new InputStreamReader(
sk.getInputStream(), "gbk"));
if (reader != null) {
String str = reader.readLine();
if (str.trim().length() > 0)
SortReply.sort(str);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

try {
sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐