在Android中,对UI的直接修改只能在UI线程中才能进行,在子线程中是无法修改的。
而为了能够控制UI的修改,我们可以使用Handler来对UI进行操作。
第一种方式:
我们可以在主线程中创建一个Handler对象,然后将Handler的引用给子线程;子线程中可以使用Handler.sendEmptyMessage(int)或者Handler.sendMessage(Message)来向Handler发送消息,对UI的操作可以在Handler.handleMessage(Message)中进行。
Message可以携带数据,Message.what可以携带整形数据,用于判断执行哪条分支,而Message.obj则可以携带对象。
第二种方式:
同样在主线程中创建Handler对象,在子线程中向Handler发送消息。
不同的是,对UI的处理我们不直接在Handler.handleMessage(Message)中执行,而是在handleMessage(Message)方法中执行Handler.post(Runnable)或者Handler.postDelay(Runnbale),而实际对UI的处理都在Runnable中进行。
这样做的好处是:可以在不再使用Handler的时候,方便地使用Handler.removeCallbacks()方法将Runnable移除,而不会导致资源已经释放,而Handler的消息队列中还存在待处理的命令,从而导致应用的崩溃。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:id="@+id/tv_count" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Hello World, MyActivity" android:gravity="center" android:padding="10dp" /> <Button android:id="@+id/btn_send" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="发送" android:layout_gravity="center" android:gravity="center" /> <Button android:id="@+id/btn_destroy" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="销毁" android:layout_gravity="center" android:gravity="center" /> </LinearLayout>
public class MyActivity extends Activity { private static final String TAG = "MyActivity"; private TextView mTvCount; private Button mBtnSend; private int count; private Runnable mRunnable; private MyHandler mHandler = new MyHandler(); /** * Called when the activity is first created. */ @Override public void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initView(); initRunnable(); } /** * 初始化视图 */ private void initView () { mTvCount = (TextView) findViewById(R.id.tv_count); mBtnSend = (Button) findViewById(R.id.btn_send); Button mBtnDestroy = (Button) findViewById(R.id.btn_destroy); mBtnSend.setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { //向Handler发送消息 mHandler.sendEmptyMessage(0); } }); mBtnDestroy.setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v) { //此处将TextView释放掉 mTvCount = null; //此处将Runnable移除掉,否则的话就会由于TextView已经被释放而导致出现空指针 mHandler.removeCallbacks(mRunnable); } }); } /** * Handler中要使用的Runnable */ private void initRunnable () { mRunnable = new Runnable() { @Override public void run () { //使用obtainMessage()来从消息队列中获取消息 Message msg = mHandler.obtainMessage(); Log.i(TAG, "what = " + msg.what); switch (msg.what) { case 0: //此处对TextView进行修改 mTvCount.setText(String.valueOf(++count)); break; } } }; } /** * 要对UI进行操作的Handler */ private class MyHandler extends Handler { @Override public void handleMessage (Message msg) { //此处可以使用post或者postDelay this.postDelayed(mRunnable, 3000); } } }