這幾天一直在看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。