以下兩個小範例示範實作 1000 毫秒的 Timer,
兩種方式需注意一點,使用 Timer 方式雖然簡單,
但 TimerTask 是在 Background Thread 被呼叫,
所以無法在 TimerTask 中直接操作 UI Element,
必須委托 main thread 的 handler 協助,
比較直觀的 Timer
import java.util.*;
public class MainActivity extends Activity
{
Timer timer = new Timer(true);
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
timer.schedule(new MyTimerTask(), 1000, 1000);
}
public class MyTimerTask extends TimerTask
{
public void run()
{
}
};
}
此外需注意的是當我們要停止這個 Timer 時,我們可以使用以下指令
timer.cancel();
已經被 cancel 後的 timer 無法再次 schedule 必須再重新 new 一個,另外如果發生 TimerTask 已經被使用的 Exception 時,記得看看是不是因為將 TimerTask 宣告為類別成員並重用了,正確的做法是每需要重新 new TimerTask 才對。
利用 Handler 做同樣的事
import android.os.Handler;
public class MainActivity extends Activity
{
public class MainActivity extends Activity
private int m_nTime = 0;
private Handler mHandlerTime = new Handler();
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
mHandlerTime.postDelayed(timerRun, 1000);
}
@Override
public void onDestroy()
{
mHandlerTime.removeCallbacks(timerRun);
super.onDestroy();
}
private final Runnable timerRun = new Runnable()
{
public void run()
{
++m_nTime; // 經過的秒數 + 1
mHandlerTime.postDelayed(this, 1000);
// 若要取消可以寫一個判斷在這決定是否啟動下一次即可
}
};
}
使用Timer如果遇到修改UI版面時會出現錯誤,藉由Handler的使用就不會出錯。就我的理解是在Android只有主Thread可以修改或是構件UI。
回覆刪除http://developer.android.com/reference/java/util/Timer.html
回覆刪除This document says "Each timer has one thread on which tasks are executed sequentially."
http://developer.android.com/guide/topics/fundamentals/processes-and-threads.html
This document says "Do not access the Android UI toolkit from outside the UI thread (main thread), or it can result in undefined and unexpected behavior."
I think that's why we can not use Timer to access the UI interface.
害人啊,无法使用timer.purge();停止timer。
回覆刪除static int count = 0;
public static void main(String[] args) throws IOException
{
Timer timer = new Timer(true);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.SECOND, 1);
timer.schedule(new TimerTask()
{
@Override
public void run()
{
System.out.println(count);
count++;
}
}, calendar.getTime(), 1000);
BufferedReader streamReader = new BufferedReader(new InputStreamReader(System.in));
streamReader.readLine();
timer.purge();
streamReader.readLine();
}
按下回车后timer仍然向控制台输出消息。
Purge 是清除已取消的 Tasks,
刪除http://developer.android.com/reference/java/util/Timer.html
purge()
Removes all canceled tasks from the task queue.
謝謝幾位的指正,已更新 :)
回覆刪除private ing m_nTime = 0;
回覆刪除是int嗎@@
我ing宣告出錯
作者已經移除這則留言。
回覆刪除感謝大大無私的分享~
回覆刪除