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},

由上可知,代码阻塞方式等待计时结束或由意外中断结束。

相关推荐