在工作线程中处理UI线程报错:Only the original thread that created a view hierarchy can touch its views.

如果将更新UI控件的代码写入到工作线程中便会报错,

例子如下:

Runnable socketRun = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			tv = (TextView) findViewById(R.id.tv);
			Socket socket = null;
			String message = et.getText().toString() + "\r\n";
			try {
				// 创建socket
				socket = new Socket("192.168.1.34", 8080);
				// 向服务器发送消息
				PrintWriter out = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream()), true);
				out.println(message);
				// 接收来自服务器的消息
				BufferedReader br = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				msgs = br.readLine();
				//下面是更新UI的代码,这样写是错误的
				if (msgs != null) {
					tv.setText(msgs);
				} else {
					tv.setText("数据错误!");
				}
				out.close();
				br.close();
				socket.close();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	};


错误如下:

 android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

因为这样会阻塞住线程。

有一下三种改法:

第一种:利用Message来传递信息给Handler来处理UI的更新问题

Runnable socketRun = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			tv = (TextView) findViewById(R.id.tv);
			Socket socket = null;
			String message = et.getText().toString() + "\r\n";
			try {
				// 创建socket
				socket = new Socket("192.168.1.34", 8080);
				// 向服务器发送消息
				PrintWriter out = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream()), true);
				out.println(message);
				// 接收来自服务器的消息
				BufferedReader br = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				msgs = br.readLine();
				//实例化message对象
				Message msg = new Message();
				//给message对象赋值
				msg.what = 1;
				//发送message值给Handler接收
				mHandler.sendMessage(msg);
				out.close();
				br.close();
				socket.close();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	};

	private Handler mHandler = new Handler() {
		public void handleMessage(Message msg) {
			// 更新UI
			switch (msg.what) {
			case 1:
				if (msgs != null) {
					tv.setText(msgs);
				} else {
					tv.setText("数据错误!");
				}
				break;
			}

		};
	};

第二种:利用Handler的post方法

Runnable socketRun = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			tv = (TextView) findViewById(R.id.tv);
			Socket socket = null;
			String message = et.getText().toString() + "\r\n";
			try {
				// 创建socket
				socket = new Socket("192.168.1.34", 8080);
				// 向服务器发送消息
				PrintWriter out = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream()), true);
				out.println(message);
				// 接收来自服务器的消息
				BufferedReader br = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				msgs = br.readLine();
				
				mHandler.post(updateThread);
				
				out.close();
				br.close();
				socket.close();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	};

	private Handler mHandler = new Handler();
	
	Runnable updateThread = new Runnable()    
	   {   
	  
	        @Override  
	        public void run()   
	        {   
	            //更新UI   
	        	if (msgs != null) {
					tv.setText(msgs);
				} else {
					tv.setText("数据错误!");
				}
	       }   
	           
	   };

第三种方法:官方推荐的方法

Runnable socketRun = new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			tv = (TextView) findViewById(R.id.tv);
			Socket socket = null;
			String message = et.getText().toString() + "\r\n";
			try {
				// 创建socket
				socket = new Socket("192.168.1.34", 8080);
				// 向服务器发送消息
				PrintWriter out = new PrintWriter(new OutputStreamWriter(
						socket.getOutputStream()), true);
				out.println(message);
				// 接收来自服务器的消息
				BufferedReader br = new BufferedReader(new InputStreamReader(
						socket.getInputStream()));
				msgs = br.readLine();
				MainActivity.this.runOnUiThread(updateThread);
				out.close();
				br.close();
				socket.close();
			} catch (UnknownHostException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	};

	Runnable updateThread = new Runnable()    
	   {   
	  
	        @Override  
	        public void run()   
	        {   
	            //更新UI   
	        	if (msgs != null) {
					tv.setText(msgs);
				} else {
					tv.setText("数据错误!");
				}
	       }   
	           
	   };   



 

 

 

 


 

你可能感兴趣的:(android,socket,在线程中更新UI的问题)