??開發(fā)中經(jīng)常遇到用計時器的時候,例如:每秒輸出一次log,這時候就要用到延時操作,這里總結了幾種常用的方法。
10多年專注成都網(wǎng)站制作,成都定制網(wǎng)頁設計,個人網(wǎng)站制作服務,為大家分享網(wǎng)站制作知識、方案,網(wǎng)站設計流程、步驟,成功服務上千家企業(yè)。為您提供網(wǎng)站建設,網(wǎng)站制作,網(wǎng)頁設計及定制高端網(wǎng)站建設服務,專注于成都定制網(wǎng)頁設計,高端網(wǎng)頁制作,對酒樓設計等多個領域,擁有多年的網(wǎng)站設計經(jīng)驗。
?? AlarmManager 是Android的全局定時器,可以在指定時間執(zhí)行定時任務。定時任務通過PendingIntent 的 getActivity()、getService()或 getBroadcast() 來執(zhí)行。簡單的說就是我們設定一個時間,然后在該時間到來時,AlarmManager為我們廣播一個我們設定的Intent出來,在接收到設定的Intent時執(zhí)行定時任務。
(2) setRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
該方法用于設置重復鬧鐘,其中參數(shù)說明如下:
type:鬧鐘類型
startTime:首次執(zhí)行鬧鐘的時間
intervalTime:兩次執(zhí)行鬧鐘的時間間隔
pi:鬧鐘響應動作
(3) setInexactRepeating(int type,long startTime,long intervalTime,PendingIntent pi);
該方法也用于設置重復鬧鐘,與第二個方法相似,區(qū)別在于其兩次鬧鐘執(zhí)行的間隔時間不是固定的。
?? AlarmManager實現(xiàn)定時的方法,我還沒有用到過,以上內(nèi)容是在網(wǎng)上查找資料后自己在一個小demo中小小試驗了的,有錯誤或描述不清的地方請見諒。下面是我參考的介紹AlarmManager的三篇文章。
你的意思是,假設3個RadioButton,第一個設為10秒,第二個設為20秒,第三個設為30秒,然后一起倒計時到0嗎?如果是這樣的話,只需要在Handler的handleMessage中去減時間就行了。
Handler
handler=new
Handler(){
@Override
public
void
handleMessage(Message
msg)
{
super.handleMessage(msg);
xx.setText(Integer.parseInt(xx.getText()-1);
}
};
可以用Service+Broadcast+Handler來實現(xiàn)。
Handler在Service里
在Service里主要邏輯為:用Handler實現(xiàn)每分鐘發(fā)送一次廣播
Broadcast在Activity里,內(nèi)部類的形式
Broadcast接收廣播并調(diào)用某某方法。
核心:Activity開啟服務,讓服務每隔一分鐘就發(fā)送一條廣播通知調(diào)用某某方法。
這是Activity里的代碼
public?class?MainActivity?extends?Activity??{
public?Intent?startService;
//發(fā)送廣播需要的Action
public?static?final?String?BROADCAST_ACTION="broadcast.action";
/**?Called?when?the?activity?is?first?created.?*/
@Override
public?void?onCreate(Bundle?savedInstanceState)?{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//在這里注冊廣播
IntentFilter?filter?=?new?IntentFilter();
filter.addAction(ConstantTool.BROADCAST_ACTION);
registerReceiver(myResver,?filter);
//設置服務
startService?=?new?Intent(MusicService.SERVICE_ACTION);
startService.setClass(this,?MusicService.class);
}
//假設這是你每分鐘都要調(diào)用一次的方法
private?void?initViews()?{
}
//這個點擊事件來控制什么時候開啟服務
private?OnClickListener?clickListener=new?OnClickListener()?{
@Override
public?void?onClick(View?v)?{
//?TODO?Auto-generated?method?stub
startService(startService);
}
};
/**
?*?廣播
?*?
?*?@author?Administrator
?*?
?*/
class?MyResver?extends?BroadcastReceiver?{
@Override
public?void?onReceive(Context?context,?Intent?intent)?{
//首先判斷你的Action是否一致
if?(BROADCAST_ACTION.equals(intent.getAction()))?{
//如果一致,那么就調(diào)用方法
initVies();
}
}
}
@Override
protected?void?onDestroy()?{
//?TODO?Auto-generated?method?stub
super.onDestroy();
//銷毀廣播
unregisterReceiver(myResver);
}
}
Service里的代碼
public?class?MusicService?extends?Service?{
//這里面的值可以隨意,因為在AndroidManifest里已經(jīng)注冊了
public?static?final?String?SERVICE_ACTION="service.action";
public?MusicService()?{
//?TODO?Auto-generated?constructor?stub
}
@Override
public?IBinder?onBind(Intent?arg0)?{
//?TODO?Auto-generated?method?stub
return?null;
}
@Override
public?void?onCreate()?{
//?TODO?Auto-generated?method?stub
super.onCreate();
}
//創(chuàng)建一個Handler
Handler?mHandler?=?new?Handler()?{
public?void?handleMessage(android.os.Message?msg)?{
int?currentTime?=?msg.arg1;
Intent?broadcast?=?new?Intent(MainActivity.BROADCAST_ACTION);
sendBroadcast(broadcast);
};
};
//創(chuàng)建一個線程
Runnable?updateThread?=?new?Runnable()?{
@Override
public?void?run()?{
if?(mMediaPlayer?!=?null)?{
Message?msg?=?mHandler.obtainMessage();
mHandler.postDelayed(updateThread,?60*1000);
}
}
};
@Override
public?void?onStart(Intent?intent,?int?startId)?{
//?TODO?Auto-generated?method?stub
super.onStart(intent,?startId);
//在這里判斷是否是啟動服務的那個Action
if?(intent.getAction().equals(SERVICE_ACTION))?{
mHandler.postDelayed(updateThread,?60*1000);
}
}
}
服務綁定
service?android:name="com.seekbar.android.service.MusicService"/
在Android上常用的定時器有兩種,一種是Java.util.Timer,一種就是系統(tǒng)的AlarmService了。
實驗1:使用Java.util.Timer。
在onStart()創(chuàng)創(chuàng)建Timer,每5秒更新一次計數(shù)器,并啟動。
Java代碼
1mTimer = new Timer();
2mTimer.schedule(new TimerTask() {
3 @Override
4 public void run() {
5 ++mCount;
6 mHandler.sendEmptyMessage(0);
7 }
8 }, 5*1000, 5*1000);
當連接USB線進行調(diào)試時,會發(fā)現(xiàn)一切工作正常,每5秒更新一次界面,即使是按下電源鍵,仍然會5秒觸發(fā)一次。
當拔掉USB線,按下電源鍵關閉屏幕后,過一段時間再打開,發(fā)現(xiàn)定時器明顯沒有繼續(xù)計數(shù),停留在了關閉電源鍵時的數(shù)字。
實驗2:使用AlarmService:
2.1通過AlarmService每個5秒發(fā)送一個廣播,setRepeating時的類型為AlarmManager.ELAPSED_REALTIME。
Java代碼
1AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
2am.setRepeating(AlarmManager.ELAPSED_REALTIME, firstTime, 5*1000, sender);
拔掉USB線,按下電源鍵,過一段時間再次打開屏幕,發(fā)現(xiàn)定時器沒有繼續(xù)計數(shù)。
2.2setRepeating是的類型設置為AlarmManager.ELAPSED_REALTIME_WAKEUP
Java代碼
1AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
2am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, 5*1000, sender);
拔掉USB線,按下電源鍵,過一點時間再次打開屏幕,發(fā)現(xiàn)定時器一直在計數(shù)。
如此看來,使用WAKEUP才能保證自己想要的定時器一直工作,但是肯定會引起耗電量的增加。
在我們Android客戶端上有時候可能有些任務不是當時就執(zhí)行,而是過了一個規(guī)定的時間在執(zhí)行此次任務。那么這個時候定時器的作用就非常有用了。首先開啟一個簡單的定時器
現(xiàn)在我就相當于定義了一個定時器,我現(xiàn)在的定時器是向服務器發(fā)送Post請求來返回數(shù)據(jù)刷新到我的界面上那么接下來就是開啟定時器了。開啟定時器那就非常簡單了
開啟定時器特別簡單基本上一句話就搞定了
開啟定時器需要三個參數(shù)
1.就是上面所寫的你要做的事情 ,上面我寫的上向網(wǎng)絡發(fā)送請求那么這里就時開啟定時器請求網(wǎng)絡
2.這個參數(shù)是你要多長時間后執(zhí)行這個定時器,這里我寫的是0,那么就是0秒后執(zhí)行我的定時器。
3.這個是最重要的這就是你每次執(zhí)行時間的間隔 我這里就是說每10秒向網(wǎng)絡發(fā)送一次請求如果寫成1000就是每一秒向網(wǎng)絡發(fā)送一次請求
如果第三個參數(shù)不寫的話那么定時器就是幾秒后執(zhí)行 那么定時器只執(zhí)行一次就不在執(zhí)行了
其實定時器如果不銷毀的話是一直執(zhí)行的但其實定時器如果一直執(zhí)行的話那么我們的程序根本就撐不了多長時間就會崩潰所以說定時器用完就要及時的關閉
定時器的開啟在寫Fragment或者Activity的時候我一般會寫在onStart里面
如果銷毀的時候會寫在onStop里面銷毀定時器也非常簡單
基本上這一句話就搞定了執(zhí)行這句話說明是注銷定時器
當我們離開本界面的時候就執(zhí)行這句話那么定時器就不會在執(zhí)行了當我們進入本界面在onStart執(zhí)行定時器那么就又開啟了定時器所以說這樣就寫了一個簡易版的定時器
一個簡單的定時器請求網(wǎng)絡就完成了 HttpHolder holder = new HttpHolder(handler); 這是自己寫的網(wǎng)絡請求類直接調(diào)用輸入url的服務器地址獲得的就是服務器發(fā)來的JSON格式的數(shù)據(jù)
在onStop里面注銷定時器那么每次離開本界面的時候那么定時候就銷毀了再回到本界面的時候那么就執(zhí)行onStart里面的開啟定時器那么定時器就開啟了所以這樣就避免了因為定時器開啟而使程序崩潰