这几天一直在看Handler的用法,今天来总结下:
你或许会遇见android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
中文意思就是只有创建这个控件的线程才能去更新该控件的内容。
为什么会这样?这就要说到android保护机制了,为了不让UI线程(主线程)阻塞,android会要求你去建议一个新的线程去操作那些费时间的操作,而且UI的更新必需在主线程中更新,这是我们就可以用Handler来实现了。
先来个简单的例子:
该例子的目的是联网取得数据后在UI中显示数据。
public class MainActivity extends Activity {
public TextView text;
private HttpParams httpParams;
private HttpClient httpClient;
private Handler handler;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
System.out.println("creat中" + Thread.currentThread().getName());
handler = new myHandler();
text = (TextView) findViewById(R.id.text);
Thread thread = new myThread();
thread.start();
}
class myThread extends Thread {
public void run() {
List<BasicNameValuePair> params = new LinkedList<BasicNameValuePair>();
params.add(new BasicNameValuePair("XX", "XXXX"));//网页的参数
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
String baseUrl = "XXXXXXXXXXXXXXXXXXXXXXX";//网址
HttpPost postMethod = new HttpPost(baseUrl);
postMethod.setEntity(new UrlEncodedFormEntity(params, "utf-8")); // 将参数填入POST
// Entity中
HttpResponse response = httpclient.execute(postMethod); // 执行POST方法
Log.v("resCode = ", String.valueOf(response.getStatusLine()
.getStatusCode())); // 获取响应码
// //获取响应内容
String s = EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(s);
//获取Message并发送参数
Message msg = handler.obtainMessage();
msg.obj = s;
handler.sendMessage(msg);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class myHandler extends Handler {
@Override
public void handleMessage(Message msg) {
System.out.println("handler中" + Thread.currentThread().getName());
String s = (String) msg.obj;//接受参数
text.setText(s);//更新UI
}
}
<pre name="code" class="java"> }
从结果可以看出,我们从主线程中更新了UI。