ADROID 2.1 架构解析 6 闹钟
6闹钟
6.1设置定时时间
文件:packages/apps/alarmclock/src/com/android/alarmclock/Alarms.java
privatestaticvoidenableAlert(Contextcontext,finalAlarmalarm,
finallongatTimeInMillis){
AlarmManageram=(AlarmManager)
context.getSystemService(Context.ALARM_SERVICE);
...
am.set(AlarmManager.RTC_WAKEUP,atTimeInMillis,sender);
...
}
由闹钟管理器设置定时时间。
6.2闹钟管理器
6.2.1定时设置
文件:frameworks/base/core/java/android/app/AlarmManager.java
publicstaticfinalintRTC_WAKEUP=0;
publicstaticfinalintRTC=1;
publicstaticfinalintELAPSED_REALTIME_WAKEUP=2;
publicstaticfinalintELAPSED_REALTIME=3;
AlarmManager(IAlarmManagerservice){
mService=service;
}
publicvoidset(inttype,longtriggerAtTime,PendingIntentoperation){
try{
mService.set(type,triggerAtTime,operation);
}catch(RemoteExceptionex){
}
}
将type,triggerAtTime,operation等参数转向闹钟管理器服务。
6.3闹钟管理器服务
文件:frameworks/base/services/java/com/android/server/AlarmManagerService.java
6.3.1定时设置
publicAlarmManagerService(Contextcontext){
mDescriptor=init();
...
}
publicvoidset(inttype,longtriggerAtTime,PendingIntentoperation){
setRepeating(type,triggerAtTime,0,operation);
}
publicvoidsetRepeating(inttype,longtriggerAtTime,longinterval,
PendingIntentoperation){
if(operation==null){
Log.w(TAG,"set/setRepeatingignoredbecausethereisnointent");
return;
}
synchronized(mLock){
Alarmalarm=newAlarm();
alarm.type=type;
alarm.when=triggerAtTime;
alarm.repeatInterval=interval;
alarm.operation=operation;
//Removethisalarmifalreadyscheduled.
removeLocked(operation);
if(localLOGV)Log.v(TAG,"set:"+alarm);
intindex=addAlarmLocked(alarm);
if(index==0){
setLocked(alarm);
}
}
}
privatevoidsetLocked(Alarmalarm)
{
if(mDescriptor!=-1)
{
set(mDescriptor,alarm.type,(alarm.when*1000*1000));
}
else
{
Messagemsg=Message.obtain();
msg.what=ALARM_EVENT;
mHandler.removeMessages(ALARM_EVENT);
mHandler.sendMessageAtTime(msg,alarm.when);
}
}
Init,set为底层操作函数,set(mDescriptor,alarm.type,(alarm.when*1000*1000));由底层来完成定时设置。
6.3.2等待计时结束
privateclassAlarmThreadextendsThread
{
publicvoidrun()
{
...
while(true)
{
intresult=waitForAlarm(mDescriptor);
...
if((result&RTC_WAKEUP_MASK)!=0)
triggerAlarmsLocked(mRtcWakeupAlarms,triggerList,nowRTC);
if((result&RTC_MASK)!=0)
triggerAlarmsLocked(mRtcAlarms,triggerList,nowRTC);
if((result&ELAPSED_REALTIME_WAKEUP_MASK)!=0)
triggerAlarmsLocked(mElapsedRealtimeWakeupAlarms,triggerList,nowELAPSED);
if((result&ELAPSED_REALTIME_MASK)!=0)
triggerAlarmsLocked(mElapsedRealtimeAlarms,triggerList,nowELAPSED);
...
}
}
}
在服务里采用线程来处理计时结束返回的信息,根据等待计时结束返回的信息触发不同的操作。
6.4硬件调用
文件:frameworks/base/services/jni/com_android_server_AlarmManagerService.cpp
6.4.1定时设置
staticjintandroid_server_AlarmManagerService_init(JNIEnv*env,jobjectobj)
{
#ifHAVE_ANDROID_OS
returnopen("/dev/alarm",O_RDWR);
#else
return-1;
#endif
}
staticvoidandroid_server_AlarmManagerService_close(JNIEnv*env,jobjectobj,jintfd)
{
#ifHAVE_ANDROID_OS
close(fd);
#endif
}
staticvoidandroid_server_AlarmManagerService_set(JNIEnv*env,jobjectobj,jintfd,jinttype,jlongnanoseconds)
{
#ifHAVE_ANDROID_OS
structtimespects;
ts.tv_sec=NANOSECONDS_TO_SECONDS(nanoseconds);
ts.tv_nsec=nanoseconds-SECONDS_TO_NANOSECONDS(ts.tv_sec);
intresult=ioctl(fd,ANDROID_ALARM_SET(type),&ts);
if(result<0)
{
LOGE("Unabletosetalarmto%lld:%s\n",nanoseconds,strerror(errno));
}
#endif
}
以上函数的绑定如下:
{"init","()I",(void*)android_server_AlarmManagerService_init},
{"close","(I)V",(void*)android_server_AlarmManagerService_close},
{"set","(IIJ)V",(void*)android_server_AlarmManagerService_set},
由上可知,通过ioctl接口,设置定时时间。
6.4.2等待计时结束
staticjintandroid_server_AlarmManagerService_waitForAlarm(JNIEnv*env,jobjectobj,jintfd)
{
#ifHAVE_ANDROID_OS
intresult=0;
do
{
result=ioctl(fd,ANDROID_ALARM_WAIT);
}while(result<0&&errno==EINTR);
if(result<0)
{
LOGE("Unabletowaitonalarm:%s\n",strerror(errno));
return0;
}
returnresult;
#endif
}
以上函数的绑定如下:
{"waitForAlarm","(I)I",(void*)android_server_AlarmManagerService_waitForAlarm},
由上可知,代码阻塞方式等待计时结束或由意外中断结束。