ADROID 2.1 架构解析 6 闹钟

来源:互联网 发布:在线aes算法 编辑:程序博客网 时间:2024/04/23 22:36

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

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

原创粉丝点击