Android系统闹钟定时功能框架,总体来说就是用数据库存储定时数据,有一个状态管理器来统一管理这些定时状态的触发和更新。在Andriod系统中实现定时功能,最终还是要用到系统提供的AlarmManager,只是当一个定时完成后怎么继续处理,或者中间怎么更新定时的时间或者状态,像闹钟这种应用程序,每天重复定时,或者一周选择其中的几天,闹钟响了延迟5分钟再次响铃,这时候就需要想一种好的办法来让管理这些数据和状态,下面就分析一下Android系统闹钟的实现。
1、基本结构
Alarm
代表一条定时数据
AlarmInstance
代表一个定时项目的实例,一个AlarmInstance对应到一个Alarm,相比Alarm多存储了一些状态信息
AlarmStateManager
状态管理器,对定时项目进行调度,添加、删除、更改状态,是一个BroadcastReciever,定时到点后发广播到这里进行下一步处理
AlarmService
响应结果,也就是定时到达后要做的事,响铃,停止响铃
ClockDataHelper
里面创建了三个表,ALARMS_TABLE,INSTANCE_TABLE,CITIES_TABLE,前两个分别对应到上面的Alarm和AlarmInstance。
[java] view plaincopyprin
private static void createAlarmsTable(SQLiteDatabase db) {
“CREATE TABLE ” + ALARMS_TABLE_NAME + ” (” +
” INTEGER PRIMARY KEY,” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” TEXT NOT NULL, ” +
” TEXT, ” +
” INTEGER NOT NULL DEFAULT 0);”);
“Alarms Table created”);
}
[java] view plaincopyprin
private static void createInstanceTable(SQLiteDatabase db) {
“CREATE TABLE ” + INSTANCES_TABLE_NAME + ” (” +
” INTEGER PRIMARY KEY,” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” INTEGER NOT NULL, ” +
” TEXT NOT NULL, ” +
” TEXT, ” +
” INTEGER NOT NULL, ” +
” INTEGER REFERENCES ” +
“(” + ClockContract.AlarmsColumns._ID + “) ” +
“ON UPDATE CASCADE ON DELETE CASCADE” +
“);”);
“Instance table created”);
}
这里说一下几个特殊的字段,对于Alarm表,DAYS_OF_WEEK表示一周内需要定时的天(闹钟有个功能是选择一周中的几天),这里是个int值,用位来表示设置的天数,源码中有个专门的类DaysOfWeek来存储和处理。
AlarmInstance表中有一个ALARM_ID,关联到一个Alarm,可以看到在AlarmInstance表里也有时间,为什么不和Alarm表合成一个表?应该是这样的,Alarm表示原始的定时项,是一个基础数据,而AlarmInstance则代表了一个使用中的定时项目,或者是一个已经激活的定时项目,它的时间是可以变化的,比如闹钟响了以后延时5分钟再响,就需要改变这里的时间,而基础数据不能变,还需要显示在那里。ALARM_STATE代表了当前定时项目的状态,具体调度都在AlarmStateManager中管理。
忘了在哪里看到的,“编程最重要的是设计数据结构,接下来是分解各种代码块”。数据结构是基础,就像建筑里的钢筋水泥砖瓦,有了基础的材料后,剩下的工作就是对这些材料处理,也就是设计具体的处理逻辑。
2、具体的类分析