搜尋此網誌

2014年12月24日 星期三

【Android】執行緒 - Runnable 與 Handler

ref:http://andcooker.blogspot.tw/2012/09/android-runnable-handler.html

Android 提供了很多執行緒的方法,在本部落格中也可以參考 Thread 與 AsyncTask,在不同的情境我們可以使用不同的方法,此篇我們介紹 Handler 如何操作 Runnable。將  Handler 想像為處理器,而 Runnable 為被處理的事件,所以一個處理器可以處理很多事件,那大略架構就會樣是: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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 迴圈來達成: 
?
1
2
3
4
5
6
7
8
9
10
11
12
13
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),每次都延後一秒來作,如此一來,作完十次不就是數完十秒了! 
?
1
2
3
4
5
6
7
8
9
10
11
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 直接更新介面,所以可以直接寫成: 
?
1
2
3
4
5
6
7
8
9
10
11
12
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 給停掉: 
?
1
2
3
4
5
6
7
8
@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (mHandler != null) {
        mHandler.removeCallbacks(runnable);
    }
}

沒有留言: