ADROID 2.1 架构解析 6 闹钟

6 闹钟
6.1 设置定时时间
文件:packages/apps/alarmclock/src/com/android/alarmclock/Alarms.java

private static void enableAlert(Context context, final Alarm alarm,

final long atTimeInMillis) {

AlarmManager am = (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

public static final int RTC_WAKEUP = 0;

public static final int RTC = 1;

public static final int ELAPSED_REALTIME_WAKEUP = 2;

public static final int ELAPSED_REALTIME = 3;



AlarmManager(IAlarmManager service) {

mService = service;

}

public void set(int type, long triggerAtTime, PendingIntent operation) {

try {

mService.set(type, triggerAtTime, operation);

} catch (RemoteException ex) {

}

}

将type, triggerAtTime, operation等参数转向闹钟管理器服务。

6.3 闹钟管理器服务
文件:frameworks/base/services/java/com/android/server/AlarmManagerService.java

6.3.1 定时设置
public AlarmManagerService(Context context) {

mDescriptor = init();

...

}

public void set(int type, long triggerAtTime, PendingIntent operation) {

setRepeating(type, triggerAtTime, 0, operation);

}



public void setRepeating(int type, long triggerAtTime, long interval,

PendingIntent operation) {

if (operation == null) {

Log.w(TAG, "set/setRepeating ignored because there is no intent");

return;

}

synchronized (mLock) {

Alarm alarm = new Alarm();

alarm.type = type;

alarm.when = triggerAtTime;

alarm.repeatInterval = interval;

alarm.operation = operation;



// Remove this alarm if already scheduled.

removeLocked(operation);



if (localLOGV) Log.v(TAG, "set: " + alarm);



int index = addAlarmLocked(alarm);

if (index == 0) {

setLocked(alarm);

}

}

}

private void setLocked(Alarm alarm)

{

if (mDescriptor != -1)

{

set(mDescriptor, alarm.type, (alarm.when * 1000 * 1000));

}

else

{

Message msg = 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等待计时结束
private class AlarmThread extends Thread

{

public void run()

{

...

while (true)

{

int result = 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 定时设置
static jint android_server_AlarmManagerService_init(JNIEnv* env, jobject obj)

{

#if HAVE_ANDROID_OS

return open("/dev/alarm", O_RDWR);

#else

return -1;

#endif

}



static void android_server_AlarmManagerService_close(JNIEnv* env, jobject obj, jint fd)

{

#if HAVE_ANDROID_OS

close(fd);

#endif

}



static void android_server_AlarmManagerService_set(JNIEnv* env, jobject obj, jint fd, jint type, jlong nanoseconds)

{

#if HAVE_ANDROID_OS

struct timespec ts;

ts.tv_sec = NANOSECONDS_TO_SECONDS(nanoseconds);

ts.tv_nsec = nanoseconds - SECONDS_TO_NANOSECONDS(ts.tv_sec);



int result = ioctl(fd, ANDROID_ALARM_SET(type), &ts);

if (result < 0)

{

LOGE("Unable to set alarm to %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 等待计时结束
static jint android_server_AlarmManagerService_waitForAlarm(JNIEnv* env, jobject obj, jint fd)

{

#if HAVE_ANDROID_OS

int result = 0;



do

{

result = ioctl(fd, ANDROID_ALARM_WAIT);

} while (result < 0 && errno == EINTR);



if (result < 0)

{

LOGE("Unable to wait on alarm: %s\n", strerror(errno));

return 0;

}



return result;

#endif

}

以上函数的绑定如下:

{"waitForAlarm", "(I)I", (void*)android_server_AlarmManagerService_waitForAlarm},

由上可知,代码阻塞方式等待计时结束或由意外中断结束。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值