Android 客户端 TCP socket出现 android.os.NetworkOnMainThreadException
这个问题主要是把网络操作放在了主线程当中,如果将套接字初始化放于一个继承thread的类当中也是算在主线程,如
public class ReceiveThread extends Thread{
Socket socket;
InputStream inputStream ;
OutputStream outputStream;
private String str;
private byte[] buffer ;
public ReceiveThread() {
// TODO Auto-generated constructor stub
// 创建一个Socket对象,并指定服务端的IP及端口号
try {
//socket = new Socket("192.168.191.1", 6800);//InetAddress.getByName(
System.out.println("还未连接1!!!");
socket=new Socket();
System.out.println("还未连接2!!!");
socket.connect(new InetSocketAddress("192.168.191.1", 6800),200);
System.out.println("连接成功!!!");
System.out.println("--step2-->>>");
// inputStream = socket.getInputStream();
System.out.println("--step3-->>>");
// outputStream = socket.getOutputStream();
System.out.println("--step4-->>>");
System.out.println("--inputStream-->>>"+inputStream.toString());
System.out.println("--outputStream-->>>"+outputStream.toString());
//向服务器端发送消息
} catch (UnknownHostException e) {
// TODO: handle exception
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
解决上面问题的其中第一种办法是:
上面的代码的套接字相当于在主线程中,这是不可取的,应当放入run()当中才行
@Override
public void run() {
Socket socket;
InputStream inputStream ;
OutputStream outputStream = null;
String str=null;
byte[] buffer ;
try {
//socket = new Socket("192.168.191.1", 6800);//InetAddress.getByName(
System.out.println("还未连接1!!!");
socket=new Socket();
System.out.println("还未连接2!!!");
socket.connect(new InetSocketAddress("192.168.191.1", 6800),200);
System.out.println("连接成功!!!");
System.out.println("--step2-->>>");
inputStream = socket.getInputStream();
System.out.println("--step3-->>>");
outputStream = socket.getOutputStream();
System.out.println("--step4-->>>");
System.out.println("--inputStream-->>>"+inputStream.toString());
System.out.println("--outputStream-->>>"+outputStream.toString());
//向服务器端发送消息
} catch (UnknownHostException e) {
// TODO: handle exception
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Message msg=new Message();
msg.what =1;
msg.obj =str;
mHandler.sendMessage(msg);
// 发送读取的数据到服务端
}
第二种解决方法:
@SuppressLint("NewApi") public class MainActivity extends Activity implements OnClickListener{
EditText edit_data=null;
Button button_connect=null;
Button button_disconnect=null;
//@SuppressLint("NewApi") 是使在主线程中能运行网络服务
@SuppressLint("NewApi") @TargetApi(Build.VERSION_CODES.GINGERBREAD) @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//是使在主线程中能运行网络服务
if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);}
edit_data=(EditText) this.findViewById(R.id.edit_data);
button_connect =(Button) this.findViewById(R.id.button_connect);
button_disconnect =(Button) this.findViewById(R.id.button_disconnect);
button_connect.setOnClickListener(this);
button_disconnect.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
Handler mHandler=new Handler(){
public void handMessage(Message msg)
{
switch (msg.what) {
case 1:
String strRcv = (msg.obj).toString();
edit_data.setText("接收到数据: " + strRcv);
Log.v("Leo: Rcv: ", strRcv);
// 显示接收到的数据
// mTextView.setText((msg.obj).toString());
break;
}
}
};
}
上面有三处注释的就是起到能在主线程中运行网络服务的作用