android 4.4 socket编程

          最近学socket,遇到如下问题:

          1.Andorra4.4是必须把socket网络连接放到线程中的,放到ui线程会出错。

          2.这一点最坑爹,坑了我两天了。采用

                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "utf-8"));

                String string = br.readLine();
                System.out.println(string);

             读取客户端socket发来的数据时,一直不能读出来,起初是怀疑线程同步的问题,同步锁啊,静态变量啊都用   

        了,依然不行,最后发现真正元凶是:用socket方式,readline如果没有得到数据会一直阻塞.得到数据也一定要读到回车才能继续,否则还是阻塞。也就是说,在线程中写数据的时候有:

                        Socket socket = new Socket("172.27.35.1", 30000);
                        os = socket.getOutputStream();
                        String string = "hello" +
"\r\n";
                        os.write(string.getBytes("utf-8"));

          必须加\r。\r是回车。\n是换行。

          3.还有一个重要问题:

  android中报错AndroidRuntimeException:This message is already in use

             Message msg = new Message();
                while (count<4) {
                     count++;
                     msg.what = count;
                     myHandler.sendMessage(msg);
               }
        出错原因知道,只要将Message msg = new Message();移到while语句里面就正常运行放在while语句外面时,你只有一个Message对象,该对象通过sendMessage()被发送,然后在handleMessage()中得到处理,而此时你的循环仍在运行,又对该对象进行赋值。导致的结果是两个线程可能同时处理一个对象,就出错了。
而放在while里面的话,每次循环开始,都重新创建了一个message对象,你是针对不同对象进行操作的,故没有问题了。
           4.主线程向子线程发送消息,需要在子线程中写个handler,然后在run()中new出来,问题是如何在主线程中得到子线程的handler呢?
 可以在子线程中写个getHandler()方法,但是必须加锁,原因是必须等到线程中把Handler初始化结束后才能通过getHandler传出去。
           
package com.example.serverdemoclient;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;
import java.net.UnknownHostException;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;

public class SendThread extends Thread {
	public Handler mHandler;
	Looper mlooper = null;
	String string;
	private final Object mSync = new Object();
	OutputStream os;

	public Handler getHandler() {
		synchronized (mSync) {
			if(mHandler == null)
				try {
					mSync.wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}			
		}
		return mHandler;
	}

	@Override
	public void run() {
		Looper.prepare();
		
		try {
			Socket socket = new Socket("172.27.35.1", 30000);
			os = socket.getOutputStream();
			String string = "hello" + "\r\n";
			os.write(string.getBytes("utf-8"));
			Log.i("tag", "write complet");
			
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		synchronized (mSync) {
			mHandler = new Handler() {

			@Override
			public void handleMessage(Message msg) {
				Log.i("tag", "new Handler");

				string = msg.obj.toString();
				try {
					os.write((string + "\r\n").getBytes("utf-8"));
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}

		};
		mSync.notifyAll();
		}
		Looper.loop();

	}
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值