Android?中的?Timer?和?TimerTask詳解

Timer 簡介(來自Gemini)
Timer 是 Java 中用于創(chuàng)建定時任務的類。它位于 java.util 包中。可以使用 Timer 來安排一次性或定期執(zhí)行的任務。
每個 Timer 對象都對應一個后臺線程。此線程負責從任務隊列中檢索任務并按計劃執(zhí)行它們。
使用 Timer
要使用 Timer,首先需要創(chuàng)建一個 Timer 對象。然后,可以使用該對象的 schedule() 方法來安排任務。
schedule() 方法有三個參數(shù):
task: 要執(zhí)行的任務delay: 任務延遲時間(以毫秒為單位)period: 任務的執(zhí)行周期(以毫秒為單位)
如果 period 為 0,則任務將只執(zhí)行一次。如果 period 大于 0,則任務將定期重復執(zhí)行。
以下是一個示例,說明如何使用 Timer 來創(chuàng)建一個每隔 1 秒打印“Hello, world!”消息的任務:
Timer timer = new Timer();
TimerTask task = new TimerTask() {
@Override
public void run() {
System.out.println("Hello, world!");
}
};
timer.schedule(task, 0, 1000);Timer 和 TimerTask
TimerTask 是一個抽象類,用于表示要由 Timer 執(zhí)行的任務。TimerTask 的 run() 方法將包含要執(zhí)行的任務的代碼。
以下是一個示例 TimerTask 類,用于在 5 秒后打印“Hello, world!”消息:
class MyTimerTask extends TimerTask {
@Override
public void run() {
System.out.println("Hello, world!");
}
}要使用 TimerTask 類,首先需要創(chuàng)建一個該類的子類。然后,可以將該子類的對象傳遞給 Timer 的 schedule() 方法。
取消 Timer 任務
可以使用 Timer 的 cancel() 方法來取消任務。
以下是一個示例,說明如何取消上例中的任務:
Java
timer.cancel();
注意事項
Timer 任務是在后臺線程中執(zhí)行的。這意味著它們不應執(zhí)行任何可能阻塞 UI 線程的操作。Timer 任務不應該長時間運行。如果需要執(zhí)行長時間運行的任務,則應使用其他方法,例如 HandlerThread。
替代方案
除了 Timer 之外,Android 還提供了一些其他用于創(chuàng)建定時任務的類和方法。這些包括:
AlarmManager: 用于設(shè)置一次性或定期警報Handler: 用于在主線程或后臺線程中排隊執(zhí)行任務JobScheduler: 用于安排在設(shè)備空閑時執(zhí)行的作業(yè)
何時使用 Timer
Timer 適用于需要在后臺執(zhí)行簡單任務的情況。例如,可以使用 Timer 來創(chuàng)建每隔幾秒刷新一次屏幕的任務或每隔幾分鐘將數(shù)據(jù)同步到服務器的任務。
但是,如果需要執(zhí)行更復雜的任務或需要確保任務在特定時間執(zhí)行,則應使用其他方法。
Timer在cancel后不可以重復調(diào)用
在timer調(diào)用了cancel后, 再次schedule報錯:
Process: com.android.sdktest, PID: 9264 java.lang.IllegalStateException: Timer already cancelled. at java.util.Timer.sched(Timer.java:404) at java.util.Timer.schedule(Timer.java:255) at com.android.sdktester.cases.TimerTester.start(TimerTester.java:24) at com.android.sdktester.MainActivity.onClick(MainActivity.java:23) at android.view.View.performClick(View.java:7322) at android.view.View.performClickInternal(View.java:7296) at android.view.View.access$3600(View.java:839) at android.view.View$PerformClick.run(View.java:28319) at android.os.Handler.handleCallback(Handler.java:900) at android.os.Handler.dispatchMessage(Handler.java:103) at android.os.Looper.loop(Looper.java:219) at android.app.ActivityThread.main(ActivityThread.java:8673) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)
在 Android 中,Timer 類用于創(chuàng)建定時任務。Timer 的 cancel() 方法可以取消所有已安排的任務并停止 Timer 線程。一旦 Timer 線程被取消,就不能再重新啟動。
Timer 線程是一個后臺線程。當 Timer 任務被取消時,Timer 線程將被終止。這意味著 Timer 線程不再能夠執(zhí)行任何新的任務。
如果嘗試在取消 Timer 線程后重新啟動它,則會拋出 **IllegalStateException** 異常。
解決這個問題需要創(chuàng)建一個新的 Timer 對象并使用新的 schedule() 方法安排新的任務。
TimerTask 也不可以重復使用
TimerTask 類用于表示要由 Timer 執(zhí)行的任務。TimerTask 的 run() 方法將包含要執(zhí)行的任務的代碼。
原因
TimerTask 類不是線程安全的。這意味著如果同一個 TimerTask 對象被多個 Timer 任務使用,則可能導致數(shù)據(jù)競爭和其他問題。
Timer.java
private void sched(TimerTask task, long time, long period) {
if (time < 0)
throw new IllegalArgumentException("Illegal execution time.");
// Constrain value of period sufficiently to prevent numeric
// overflow while still being effectively infinitely large.
if (Math.abs(period) > (Long.MAX_VALUE >> 1))
period >>= 1;
synchronized(queue) {
if (!thread.newTasksMayBeScheduled)
throw new IllegalStateException("Timer already cancelled.");
synchronized(task.lock) {
**if (task.state != TimerTask.VIRGIN)**
throw new IllegalStateException(
"Task already scheduled or cancelled");
task.nextExecutionTime = time;
task.period = period;
task.state = TimerTask.SCHEDULED;
}
queue.add(task);
if (queue.getMin() == task)
queue.notify();
}
}TimerTask.java
public boolean cancel() {
synchronized(lock) {
boolean result = (state == SCHEDULED);
state = CANCELLED;
return result;
}
}為了避免這些問題,應為每個 Timer 任務創(chuàng)建一個新的 TimerTask 對象。
一個 Timer 可以同時計劃多個 TimerTask。
Timer 類用于創(chuàng)建定時任務。Timer 的 schedule() 方法可以安排一個或多個任務。
以下是一個示例,說明如何使用 schedule() 方法安排多個任務:
Timer timer = new Timer();
TimerTask task1 = new TimerTask() {
@Override
public void run() {
System.out.println("Task 1");
}
};
TimerTask task2 = new TimerTask() {
@Override
public void run() {
System.out.println("Task 2");
}
};
timer.schedule(task1, 0, 1000);
timer.schedule(task2, 500, 1000);在這個示例中,task1 將在 0 毫秒后立即執(zhí)行,然后每隔 1 秒重復執(zhí)行一次。task2 將在 500 毫秒后執(zhí)行,然后每隔 1 秒重復執(zhí)行一次。
Timer 如何管理多個任務
Timer 使用一個隊列來存儲已安排的任務。Timer 線程負責從隊列中檢索任務并按計劃執(zhí)行它們。
當 Timer 任務被安排時,它將被添加到隊列的末尾。Timer 線程將從隊列的頭部檢索任務。這意味著最先安排的任務將首先執(zhí)行。
如果有多個任務在同一時間就緒,則 Timer 線程將按 FIFO(先進先出)的順序執(zhí)行它們。
注意事項
- Timer 任務是在后臺線程中執(zhí)行的。這意味著它們不應執(zhí)行任何可能阻塞 UI 線程的操作。
- Timer 任務不應該長時間運行。如果需要執(zhí)行長時間運行的任務,則應使用其他方法,例如 HandlerThread。
只要Timer不cancel, 可以反復計劃新的任務
Timer timer = new Timer();
TimerTask t1, t2, t3;
//省略創(chuàng)建TimerTask代碼....
{
timer.schedule(t1, 0, 1000);
timer.schedule(t2, 0, 1000;
Thread.sleep(10 * 1000);//等待10秒
t1.cancel();
t2.cancel();
Thread.sleep(5000);
timer.schedule(t3, 0, 1000;
Thread.sleep(5000);
t3.cancel();
}
timer.cancel()這段代碼使用了 Thread.sleep() 方法來控制任務的執(zhí)行順序。在 Thread.sleep() 方法執(zhí)行期間,Timer 線程無法從任務隊列中檢索任務,因此即使 t1 和 t2 任務已經(jīng)被取消,它們也不會再被執(zhí)行。使用了 t1.cancel() 和 t2.cancel() 方法來顯式地將 t1 和 t2 任務從 Timer 的任務隊列中刪除。這可以確保這兩個任務不會再次被執(zhí)行.
參考
Android 開發(fā)Timer與TimerTask - 觀心靜
到此這篇關(guān)于Android 的 Timer 和 TimerTask的文章就介紹到這了,更多相關(guān)Android Timer 和 TimerTask內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android開發(fā)中Eclipse報錯及對應處理方法總結(jié)
這篇文章主要介紹了Android開發(fā)中Eclipse報錯及對應處理方法,實例匯總了使用eclipse開發(fā)Android項目過程中常見的錯誤提示及對應的處理技巧,需要的朋友可以參考下2015-12-12
monkeyrunner環(huán)境搭建及實例教程(3)
這篇文章主要為大家詳細介紹了monkeyrunner環(huán)境搭建及實例教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-11-11
Android編程實現(xiàn)基于BitMap獲得圖片像素數(shù)據(jù)的方法
這篇文章主要介紹了Android編程實現(xiàn)基于BitMap獲得圖片像素數(shù)據(jù)的方法,對比分析了兩種獲取圖片像素的技巧,具有一定參考借鑒價值,需要的朋友可以參考下2015-11-11
移動端android上line-height不居中的問題的解決
現(xiàn)在越來越多的移動界面使用rem適配,最近發(fā)現(xiàn)了移動端android上line-height不居中的問題,今日就來介紹一下解決的方法,非常具有實用價值,需要的朋友可以參考下2018-03-03
Android 自定義ProgressDialog進度條對話框用法詳解
ProgressDialog為進度對話框。android手機自帶的對話框顯得比較單一,我們可以通過ProgressDialog來自己定義對話框中將要顯示出什么東西2016-01-01
Android SlidingDrawer 抽屜效果的實現(xiàn)
本篇文章小編為大家介紹,Android SlidingDrawer 抽屜效果的實現(xiàn)。需要的朋友參考下2013-04-04

