1澳眷、普通線程sleep的方式,可用于一般的輪詢(xún)Polling
? ? ? new Thread(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? while (true) {
? ? ? ? ? ? ? ? ? ? //todo
? ? ? ? ? ? ? ? ? ? try {
? ? ? ? ? ? ? ? ? ? ? ? Thread.sleep(iDelay);
? ? ? ? ? ? ? ? ? ? } catch (InterruptedException e) {
? ? ? ? ? ? ? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }).start();
優(yōu)點(diǎn):非常簡(jiǎn)單的實(shí)現(xiàn)助琐,邏輯清晰明了,也是最常見(jiàn)的寫(xiě)法
缺點(diǎn):在sleep結(jié)束后航罗,并不能保證競(jìng)爭(zhēng)到cpu資源酿箭,這也就導(dǎo)致了下次執(zhí)行時(shí)間必定>=iDelay妇蛀,存在時(shí)間精度問(wèn)題
2、Timer定時(shí)器
? ? //Timer + TimerTask結(jié)合的方法
? ? private final Timer timer = new Timer();
? ? private TimerTask timerTask = new TimerTask() {
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? //todo
? ? ? ? }
? ? };
啟動(dòng)定時(shí)器方法:
timer.schedule(TimerTask task, long delay, long period)
立即執(zhí)行
timer.schedule(timerTask, 0, 1000); //立刻執(zhí)行评架,間隔1秒循環(huán)執(zhí)行
延時(shí)執(zhí)行
timer.schedule(timerTask, 2000, 1000); //等待2秒后再執(zhí)行眷茁,間隔1秒循環(huán)執(zhí)行
關(guān)閉定時(shí)器方法:timer.cancel();
優(yōu)點(diǎn):純正的定時(shí)任務(wù),純java SDK纵诞,單獨(dú)線程執(zhí)行上祈,比較安全,而且還可以在運(yùn)行過(guò)程中取消執(zhí)行
缺點(diǎn):基于單線程執(zhí)行,多個(gè)任務(wù)之間會(huì)相互影響登刺,多個(gè)任務(wù)的執(zhí)行是串行的籽腕,性能較低,而且timer也無(wú)法保證時(shí)間精確度塘砸,是因?yàn)槭謾C(jī)休眠的時(shí)候节仿,無(wú)法喚醒cpu,不適合后臺(tái)任務(wù)的定時(shí)
3掉蔬、ScheduledExecutorService
? ? private Runnable runnable2 = new Runnable() {
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? //todo
? ? ? ? }
? ? };
? ? ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
? ? executor.scheduleAtFixedRate(runnable2, 0, 1, TimeUnit.SECONDS);
關(guān)于scheduleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 方法說(shuō)明:
command:需要執(zhí)行的線程
initialDelay:第一次執(zhí)行需要延時(shí)的時(shí)間廊宪,如若立即執(zhí)行,則initialDelay = 0
period:固定頻率女轿,周期性執(zhí)行的時(shí)間
unit:時(shí)間單位箭启,常用的有MILLISECONDS、SECONDS和MINUTES等蛉迹,需要注意的是傅寡,這個(gè)單位會(huì)影響initialDelay和period,如果unit = MILLISECONDS北救,則initialDelay和period傳入的是毫秒荐操,如果unit = SECONDS,則initialDelay和period傳入的是秒
補(bǔ)充一下: 還有一個(gè)方法跟上面的很相似:scheduleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit)珍策,這個(gè)也是帶延遲時(shí)間的調(diào)度托启,并且也是循環(huán)執(zhí)行,唯一的不同就是固定延遲時(shí)間循環(huán)執(zhí)行攘宙,上面的是固定頻率的循環(huán)執(zhí)行屯耸。那這兩者的區(qū)別?
舉例子:
使用scheduleAtFixedRate蹭劈,任務(wù)初始延遲3秒疗绣,任務(wù)執(zhí)行3秒,任務(wù)執(zhí)行間隔為5秒:
? ? ? ? ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
? ? ? ? Log.e(TAG, "schedule just start! time =" +? simpleDateFormat.format(System.currentTimeMillis()));
? ? ? ? executor.scheduleAtFixedRate(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? SystemClock.sleep(3000L);
? ? ? ? ? ? ? ? Log.e(TAG, "runnable just do it! time =" +? simpleDateFormat.format(System.currentTimeMillis()));
? ? ? ? ? ? }
? ? ? ? }, 3, 5, TimeUnit.SECONDS);
執(zhí)行結(jié)果截圖:
使用scheduleWithFixedDelay铺韧,任務(wù)初始延遲3秒多矮,任務(wù)執(zhí)行3秒,任務(wù)執(zhí)行延遲為5秒:
? ? ? ? ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
? ? ? ? Log.e(TAG, "schedule just start! time =" +? simpleDateFormat.format(System.currentTimeMillis()));
? ? ? ? executor.scheduleWithFixedDelay(new Runnable() {
? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? SystemClock.sleep(3000L);
? ? ? ? ? ? ? ? Log.e(TAG, "runnable just do it! time =" +? simpleDateFormat.format(System.currentTimeMillis()));
? ? ? ? ? ? }
? ? ? ? }, 3, 5, TimeUnit.SECONDS);
執(zhí)行結(jié)果截圖:
從這兩者的運(yùn)行結(jié)果就可以看到區(qū)別了:scheduleAtFixedRate是相對(duì)于任務(wù)執(zhí)行的開(kāi)始時(shí)間哈打,而scheduleWithFixedDelay是相對(duì)于任務(wù)執(zhí)行的結(jié)束時(shí)間塔逃。
優(yōu)點(diǎn):ScheduledExecutorService是一個(gè)線程池,其內(nèi)部使用的延遲隊(duì)列前酿,本身就是基于等待/喚醒機(jī)制實(shí)現(xiàn)的,所以CPU并不會(huì)一直繁忙鹏溯。解決了Timer&TimerTask存在的問(wèn)題罢维,多任務(wù)處理時(shí)效率高
缺點(diǎn):取消時(shí)需要打斷線程池的運(yùn)行,而且和外界的通信不太好處理
4、使用Handler中的postDelayed方法
? ? private Handler mHandler = new Handler();
? ? private Runnable runnable = new Runnable() {
? ? ? ? @Override
? ? ? ? public void run() {
? ? ? ? ? ? //todo
? ? ? ? ? ? mHandler.postDelayed(this, iDelay);
? ? ? ? }
? ? };
? ? mHandler.post(runnable); //立即執(zhí)行
? ? mHandler.postDelayed(runnable, iDelay); //延時(shí)執(zhí)行
? ? mHandler.removeCallbacks(runnable); //取消執(zhí)行
優(yōu)點(diǎn):比較簡(jiǎn)單的android實(shí)現(xiàn)肺孵,適用UI線程
缺點(diǎn):沒(méi)想到匀借,手動(dòng)捂臉。平窘。吓肋。。我估計(jì)是使用不當(dāng)會(huì)造成內(nèi)存泄露吧
5瑰艘、Service + AlarmManger + BroadcastReceiver