关于Handler的使用

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

}
原文地址:https://www.cnblogs.com/chenchong/p/3256192.html