Android 客户端 TCP socket出现 android.os.NetworkOnMainThreadException

本文讨论了在Android客户端TCP socket编程时遇到的'android.os.NetworkOnMainThreadException'错误,该错误源于在主线程执行网络操作。解决方案包括将套接字初始化移到子线程和使用AsyncTask等异步处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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;
			
		}
		 
	 }
 };
}

上面有三处注释的就是起到能在主线程中运行网络服务的作用



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值