extends:http://blog.csdn.net/superjunjin/article/details/7540064
序效果:为了显示如何用message传值的简单例子
例1,点击按钮,持续显示当前系统时间(bundle传值,耗时,效率低)
例2,点击按钮,progressbar持续前进(message方法传值,效率高,但只能传整型int和对象object)
例1,主activity
package com.song; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class C91_HandlerActivity extends Activity { /** Called when the activity is first created. */ TextView textview; Button button; MyThread mythread; Thread thread; MyHandler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); textview=(TextView)findViewById(R.id.textview); button=(Button)findViewById(R.id.button); handler=new MyHandler(); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub mythread=new MyThread(); thread=new Thread(mythread); thread.start(); } }); } class MyHandler extends Handler { //接受message的信息 @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if(msg.what==1) { textview.setText(msg.getData().getString("time")); } } } class MyThread implements Runnable { @Override public void run() { // TODO Auto-generated method stub while(true) { try { Thread.sleep(1000); String time=new SimpleDateFormat("yyyy/MM/dd HH:mm:ss").format(new Date()); System.out.println(time); Message message=new Message(); Bundle bundle=new Bundle(); bundle.putString("time", time); message.setData(bundle);//bundle传值,耗时,效率低 handler.sendMessage(message);//发送message信息 message.what=1;//标志是哪个线程传数据 //message有四个传值方法, //两个传int整型数据的方法message.arg1,message.arg2 //一个传对象数据的方法message.obj //一个bandle传值方法 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="开始" android:id="@+id/button"/> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textSize="20dp" android:textStyle="bold" android:id="@+id/textview"/> </LinearLayout>
例2,主activity
package com.song; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ProgressBar; public class C92_Handler2Activity extends Activity { /** Called when the activity is first created. */ Button button; ProgressBar bar; MyThread mythread; Thread thread; MyHandler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); button=(Button)findViewById(R.id.button); bar=(ProgressBar)findViewById(R.id.bar); handler=new MyHandler(); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub mythread=new MyThread(); thread=new Thread(mythread); thread.start(); } }); } class MyHandler extends Handler { @Override public void handleMessage(Message msg) { // TODO Auto-generated method stub super.handleMessage(msg); if(msg.what==1) { System.out.println(msg.arg1+"handle"); bar.setProgress(msg.arg1); } } } class MyThread implements Runnable { int pro=0; @Override public void run() { // TODO Auto-generated method stub while(true) { try { Thread.sleep(1000); pro=bar.getProgress()+1; bar.setProgress(pro); System.out.println(pro+"thread"); Message message=new Message(); message.arg1=pro; message.what=1; handler.sendMessage(message); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } } }
布局文件
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/button" android:text="开始" /> <ProgressBar android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/bar" style="@android:style/Widget.ProgressBar.Horizontal" /> </LinearLayout>
显示效果
、
-------------------------------------------------------------
extends:http://blog.csdn.net/shenyuemei/article/details/11030679
在工作线程中处理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() + " "; 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() + " "; 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(); <span style="color:#000000;">//实例化message对象 Message msg = new Message(); //给message对象赋值 msg.what = 1; //发送message值给Handler接收 mHandler.sendMessage(msg); </span> 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(); } } }; <span style="color:#000000;">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; } }; };</span>
第二种:利用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() + " "; 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(); <span style="color:#000000;">mHandler.post(updateThread); </span> 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(); } } }; <span style="color:#000000;">private Handler mHandler = new Handler(); Runnable updateThread = new Runnable() { @Override public void run() { //更新UI if (msgs != null) { tv.setText(msgs); } else { tv.setText("数据错误!"); } } };</span>
第三种方法:官方推荐的方法