Android 更新UI的两种方法——handler和runOnUiThread()
在Android开发过程中,常需要更新界面的UI。而更新UI是要主线程来更新的,即UI线程更新。如果在主线线程之外的线程中直接更新页面显示常会报错。抛出异常:android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
只有原始创建这个视图层次(view hierachy)的线程才能修改它的视图(view)
方法一:
在Activity.onCreate(Bundle savedInstanceState)中创建一个Handler类的实例, 在这个Handler实例的handleMessage回调函数中调用更新界面显示的函数。
方法二:
利用Activity.runOnUiThread(Runnable)把更新ui的代码创建在Runnable中,然后在需要更新ui时,把这个Runnable对象传给Activity.runOnUiThread(Runnable)。 这样Runnable对像就能在ui程序中被调用。如果当前线程是UI线程,那么行动是立即执行。如果当前线程不是UI线程,操作是发布到事件队列的UI线程
代码如下:
package com.viewpagerindicator.transitionframework; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.TextView; public class SixActivity extends AppCompatActivity { private UIHandler mUiHandler; private TextView mTvHandler; private TextView mTvRunonuithread; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_six); mTvHandler = (TextView) findViewById(R.id.tv_handler); mTvRunonuithread = (TextView) findViewById(R.id.tv_runonuithread); Button btnHandler = (Button) findViewById(R.id.btn_handler); Button btnRunonuithread = (Button) findViewById(R.id.btn_runonuithread); btnHandler.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { mUiHandler = new UIHandler(); UIThread uiThread = new UIThread(); uiThread.start(); } }); btnRunonuithread.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //此处其实可以不需要加入runOnUiThread,只是为了介绍runOnUiThread而已 SixActivity.this.runOnUiThread(new Runnable() { @Override public void run() { mTvRunonuithread.setText("这是第二个UI"); } }); } }); } private class UIHandler extends Handler { @Override public void handleMessage(Message msg) { Bundle bundle = msg.getData(); String color = bundle.getString("color"); mTvHandler.setText(color); } } private class UIThread extends Thread{ @Override public void run() { super.run(); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } Message msg = new Message(); Bundle bundle = new Bundle(); bundle.putString("color","黄色"); msg.setData(bundle); SixActivity.this.mUiHandler.sendMessage(msg); } } }