關於Handler的使用

    在Android中,對UI的直接修改只能在UI線程中才能進行,在子線程中是沒法修改的。java

    而爲了可以控制UI的修改,咱們能夠使用Handler來對UI進行操做。android

    第一種方式:ide

    咱們能夠在主線程中建立一個Handler對象,而後將Handler的引用給子線程;子線程中能夠使用Handler.sendEmptyMessage(int)或者Handler.sendMessage(Message)來向Handler發送消息,對UI的操做能夠在Handler.handleMessage(Message)中進行。post

    Message能夠攜帶數據,Message.what能夠攜帶整形數據,用於判斷執行哪條分支,而Message.obj則能夠攜帶對象。this

    第二種方式:線程

    一樣在主線程中建立Handler對象,在子線程中向Handler發送消息。指針

    不一樣的是,對UI的處理咱們不直接在Handler.handleMessage(Message)中執行,而是在handleMessage(Message)方法中執行Handler.post(Runnable)或者Handler.postDelay(Runnbale),而實際對UI的處理都在Runnable中進行。code

    這樣作的好處是:能夠在再也不使用Handler的時候,方便地使用Handler.removeCallbacks()方法將Runnable移除,而不會致使資源已經釋放,而Handler的消息隊列中還存在待處理的命令,從而致使應用的崩潰。xml

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

}
相關文章
相關標籤/搜索