2010-07-12 32 views
7

Tôi cần chạy một tác vụ định kỳ trong một ứng dụng Android. Tôi hiện đang sử dụng một bộ đếm thời gian như thế này:Thay đổi đồng hồ hệ thống Android ngừng hẹn giờ. Làm thế nào tôi có thể khởi động lại chúng?

final Handler guiHandler = new Handler(); 

// the task to run 
final Runnable myRunnable = new Runnable() { 

    @Override 
    public void run() { 
     doMyStuff(); 
    } 
}; 

Timer timer = new Timer(); 
timer.schedule(new TimerTask() { 

    @Override 
    public void run() { 
     guiHandler.post(myRunnable); 
    } 
}, 0, 30000); // run every 30 seconds 

này thực hiện chính xác những gì tôi cần, nhưng có một vấn đề: nếu tôi thay đổi thời gian trên giả lập hoặc điện thoại, bộ đếm thời gian ngừng chạy. Đây là nội dung xuất hiện trong nhật ký khi tôi thay đổi thời gian:

D/SystemClock( 331): Setting time of day to sec=1278920137 
W/SystemClock( 331): Unable to set rtc to 1278920137: Invalid argument 

Không có gì về hẹn giờ bị gián đoạn, nhưng rõ ràng không chạy nữa sau khi đồng hồ hệ thống thay đổi. Tôi cần nhiệm vụ tiếp tục chạy mọi lúc miễn là ứng dụng đang chạy.

Làm cách nào để khởi động lại bộ hẹn giờ nếu nó bị dừng như thế này? Không có phương pháp nào trên Bộ hẹn giờ hoặc TimerTask để kiểm tra xem nó có đang chạy hay không, vì vậy tôi không thể biết khi nào lên lịch lại nó. Bất kỳ ý tưởng?

Trả lời

3

Tôi nghĩ có một số cách để thực hiện việc này. Tôi sẽ không sử dụng bộ hẹn giờ trong cả hai trường hợp.

Bạn có thể sử dụng trình xử lý để chạy tác vụ của mình trong cuộc gọi postDelayed. Nhiệm vụ của bạn sau đó sẽ phải đăng ký lại chính nó với trình xử lý từ bên trong chính nó.

final int ONE_SECOND = 1000; // one second 
final Handler handler = new Handler(); 
handler.postDelayed(new Runnable() { 
    public void run() { 
     ... // do some stuff 
     if (expression) { 
     handler.postDelayed(this, ONE_SECOND); 
     } 
    } 
}, ONE_SECOND); 

Thao tác này sẽ tiếp tục chạy khi ứng dụng của bạn còn hoạt động. Bạn cũng có thể điều chỉnh tốc độ trì hoãn trong postDelayed trong Runnable. Bằng cách này, bạn có thể dự đoán được chừng nào bạn còn tạo ra một Looper khác. Sử dụng chủ đề chính có thể hoặc không phù hợp tùy thuộc vào nhiệm vụ là gì.

Ngoài ra còn có một AlarmManager, bạn có thể truy cập thông qua giao diện ngữ cảnh, có nghĩa là cho nhiệm vụ nhiệm vụ định kỳ tại các khoảng chính xác hơn. Đó là một chút phức tạp hơn để sử dụng nhưng bạn nhận được sự linh hoạt của việc sử dụng RTC và các nhiệm vụ lặp lại liên tục.

AlarmManager manager = mContext.getSystemService(Context.ALARM_SERVICE); 
manager.setRepeating(AlarmManager.RTC, 
    <start_time_millis>, 
    <period_millis>, 
    pendingIntent); 

Ví dụ: mục đích đang chờ có thể kích hoạt mục đích phát sóng mà bạn có thể nghe ở nơi khác. Bạn có thể tạo sự chờ đợi này trong onCreate của đối tượng Application tùy chỉnh của bạn và hủy bỏ ý định trong onTerminate().

+0

đây là giải pháp tuyệt vời mà tôi đang tìm kiếm! cảm ơn – JosephT

Các vấn đề liên quan