今天写了一个更新UI的小例子,没想到出了log打印了这样一个错误:Only the original thread that created a view hierarchy can touch its views。goolgle了一下找到了原因。

原来android中相关的view和控件不是线程安全的,我们必须单独做处理。这里借此引出Handler的使用。


Handler的官方描述:


A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue. When you create a new Handler, it is bound to the thread / message queue of the thread that is creating it -- from that point on, it will deliver messages and runnables to that message queue and execute them as they come out of the message queue



.Handler的使用场合:


1、 to schedule messages and runnables to be executed as some point in the future;

     安排messages和runnables在将来的某个时间点执行。

2、 to enqueue an action to be performed on a different thread than your own.

     将action入队以备在一个不同的线程中执行。即可以实现线程间通信。比如当你创建子线程时,你可以再你的子线程中拿到父线程中创建的Handler对象,就可以通过该对象向父线程的消息队列发送消息了。由于Android要求在UI线程中更新界面,因此,可以通过该方法在其它线程中更新界面。



通过Handler更新UI实例:


步骤:

1、创建Handler对象(此处创建于主线程中便于更新UI)。

2、构建Runnable对象,在Runnable中更新界面。

3、在子线程的run方法中向UI线程post,runnable对象来更新UI。


详细代码如下:

[java] view plain copy
  1. package djx.android;  

  2. import djx.downLoad.DownFiles;  

  3. import android.app.Activity;  

  4. import android.os.Bundle;  

  5. import android.os.Handler;  

  6. import android.view.View;  

  7. import android.view.View.OnClickListener;  

  8. import android.widget.Button;  

  9. import android.widget.TextView;  

  10. publicclass downLoadPractice extends Activity {  

  11. private Button button_submit=null;  

  12. private TextView textView=null;  

  13. private String content=null;  

  14. private Handler handler=null;  

  15. /** Called when the activity is first created. */

  16. @Override

  17. publicvoid onCreate(Bundle savedInstanceState) {  

  18. super.onCreate(savedInstanceState);  

  19.        setContentView(R.layout.main);  

  20. //创建属于主线程的handler

  21.        handler=new Handler();  

  22.        button_submit=(Button)findViewById(R.id.button_submit);  

  23.        textView=(TextView)findViewById(R.id.textView);  

  24.        button_submit.setOnClickListener(new submitOnClieckListener());  

  25.    }  

  26. //为按钮添加监听器

  27. class submitOnClieckListener implements OnClickListener{  

  28. @Override

  29. publicvoid onClick(View v) {  

  30. //本地机器部署为服务器,从本地下载a.txt文件内容在textView上显示        

  31. final DownFiles df=new DownFiles("http://192.168.75.1:8080/downLoadServer/a.txt");  

  32.            textView.setText("正在加载......");  

  33. new Thread(){  

  34. publicvoid run(){    

  35.                    content=df.downLoadFiles();      

  36.                    handler.post(runnableUi);  

  37.                    }                    

  38.            }.start();                        

  39.        }  

  40.    }  

  41. // 构建Runnable对象,在runnable中更新界面

  42.    Runnable   runnableUi=new  Runnable(){  

  43. @Override

  44. publicvoid run() {  

  45. //更新界面

  46.            textView.setText("the Content is:"+content);  

  47.        }  

  48.    };  

  49. }  

转载自:http://blog.csdn.net/djx123456/article/details/6325983