在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);
}
}
}