[轉] Android 執行緒 - Runnable 與 Handler

Android 提供了很多執行緒的方法,在本部落格中也可以參考 Thread 與 AsyncTask,在不同的情境我們可以使用不同的方法,此篇我們介紹 Handler 如何操作 Runnable。將 Handler 想像為處理器,而 Runnable 為被處理的事件,所以一個處理器可以處理很多事件,那大略架構就會樣是:

public class MainActivity extends Activity {
    Handler mHandler;
    TextView txtCount;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        txtCount = (TextView) findViewById(R.id.txtCount);

        mHandler = new Handler();
        mHandler.post(runnable);
    }

    final Runnable runnable = new Runnable() {
        public void run() {
            // TODO Auto-generated method stub
            // 需要背景作的事
                  }
    };
}

接下來,一樣設計數到十的背景程序,但我們會有兩種作法,先看第一種作法,我們只執行一次 Runnable,利用 for 迴圈來達成:

final Runnable runnable = new Runnable() {
    public void run() {
        // TODO Auto-generated method stub
        // 需要背景作的事
                  try {
            for (int i = 0; i < 10; i++) {
                Thread.sleep(1000);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
     }
};

另一種是,不斷的調用 Runnable 但使用 postDelayed(runnable, 1000),每次都延後一秒來作,如此一來,作完十次不就是數完十秒了!

int count = 0;
final Runnable runnable = new Runnable() {
    public void run() {
        // TODO Auto-generated method stub
        // 需要背景作的事
                   if (count < 10) {
            count++;
            mHandler.postDelayed(runnable, 1000);
        }
    }
};

但是與 Thread 不同的是,我們可以在 Runnble 直接更新介面,所以可以直接寫成:

int count = 0;
final Runnable runnable = new Runnable() {
    public void run() {
        // TODO Auto-generated method stub
        // 需要背景作的事
                  if (count < 10) {
            txtCount.setText(Integer.toString(count+1));
            count++;
            mHandler.postDelayed(runnable, 1000);
        }
    }
};

我們仍然要妥善管理,所以在 Activity 被結束時,也請 Handler 把 Runnable 給停掉:

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (mHandler != null) {
        mHandler.removeCallbacks(runnable);
    }
}

Ref : http://andcooker.blogspot.tw/