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

来源:互联网 发布:nginx 允许指定ip访问 编辑:程序博客网 时间:2024/05/22 02:11

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

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

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

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

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

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


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

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

@Overridepublic void run() {// TODO Auto-generated method stubsuper.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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}} else if (!sk.isConnected()) {try {sk.connect(new InetSocketAddress(ipStr, port));} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();Log.v(TAG, "error:can not connect socket ");}}}@Overridepublic void run() {// TODO Auto-generated method stubsuper.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 blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.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 blocke.printStackTrace();}}}public class getInputStreamThread extends Thread {public int aa = 0;@Overridepublic void run() {// TODO Auto-generated method stubsuper.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 blocke.printStackTrace();}try {sleep(3000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}


原创粉丝点击