参考:http://blog.csdn.net/x86android/article/details/14161981
http://geeksun.iteye.com/blog/1447708
Android中的线程
在Android平台中多线程应用很广泛,在UI更新、游戏开发和耗时处理(网络通信等)等方面都需要多线程。Android线程涉及的技术有:Handler;Message;MessageQueue;Looper;HandlerThread。
有一点要非常注意的,就是在写这个多线程代码的时候,遇到了两个错误:第一个是
android.os.NetworkOnMainThreadException异常;第二个是Only the original thread that created a view hierarchy can touch its views异常。
出现android.os.NetworkOnMainThreadException异常的原因是,在4.0以上Android中,访问网络不能在主线程中,否则会报错。出现第二个Only the original thread that created a view hierarchy can touch its views异常的原因是,Android中更新UI处理必须由创建它的线程更新,而不能在其他线程中更新,处理方法是通过message和handler的机制来刷新主线程UI。
正确代码如下:
package com.example.MyStarRss; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.Button; import android.widget.TextView; public class MyStarRssActivity extends Activity { /** * Called when the activity is first created. */ private TextView showTextView; private String data = ""; private Handler handler; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button startDownload_button = (Button)findViewById(R.id.start_download); showTextView = (TextView)findViewById(R.id.showdata_textview); startDownload_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 启动下载任务 new Thread(downtask).start(); } }); handler = new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch(msg.what){ case 0: showTextView.setText(msg.obj.toString()); } } }; } Runnable downtask = new Runnable() { @Override public void run() { MyHttpDownLoader myHttpDownLoader = new MyHttpDownLoader("http://rss.sina.com.cn/ent/hot_roll.xml"); String mydata = myHttpDownLoader.starDownload_Text(); Message msg = new Message(); msg.obj = mydata; msg.what = 0; handler.sendMessage(msg); } }; }
通过代码可以看出,启动多线程后,子线程要通过message和handler来与主线程进行通信。子线程启动之后,在完成下载任务时会向handler发送一个message, 通知主线程下载已经完成,然后通过主线程来更新UI。