现在的位置: 首页 > 综合 > 正文

Android4.4电源管理——回调函数

2017年10月04日 ⁄ 综合 ⁄ 共 4060字 ⁄ 字号 评论关闭

1、基本概念:

(1)什么是回调函数?
  
简而言之,回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用为调用它所指向的函数时,我们就说这是回调函数。
(2)为什么要使用回调函数?
  
因为可以把调用者与被调用者分开。调用者不关心谁是被调用者,所有它需知道的,只是存在一个具有某种特定原型、某些限制条件(如返回值为int)的被调用函数。
  
如果想知道回调函数在实际中有什么作用,先假设有这样一种情况,我们要编写一个库,它提供了某些排序算法的实现,如冒泡排序、快速排序、shell排序、shake排序等等,但为使库更加通用,不想在函数中嵌入排序逻辑,而让使用者来实现相应的逻辑;或者,想让库可用于多种数据类型(int、float、string),此时,该怎么办呢?可以使用函数指针,并进行回调。

2、Android中的回调函数/对象

2.1、JNI层到JAVA层

com_android_server_power_PowerManagerService.cpp

//回调函数声明

static struct {
    jmethodID wakeUpFromNative;
    jmethodID goToSleepFromNative;
    jmethodID userActivityFromNative;
} gPowerManagerServiceClassInfo;

int register_android_server_PowerManagerService(JNIEnv* env) {

    //注册JNI函数,供JAVA层调用。JAVA——》JNI

    int res = jniRegisterNativeMethods(env, "com/android/server/power/PowerManagerService",
            gPowerManagerServiceMethods, NELEM(gPowerManagerServiceMethods));
    LOG_FATAL_IF(res < 0, "Unable to register native methods.");

    // 注册回调函数,使JNI层可以调用JAVA层函数。JNI——》JAVA

    jclass clazz;
    FIND_CLASS(clazz, "com/android/server/power/PowerManagerService");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.wakeUpFromNative, clazz,
            "wakeUpFromNative", "(J)V");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.goToSleepFromNative, clazz,
            "goToSleepFromNative", "(JI)V");

    GET_METHOD_ID(gPowerManagerServiceClassInfo.userActivityFromNative, clazz,
            "userActivityFromNative", "(JII)V");

    // 初始化本地全局变量
    for (int i = 0; i <= USER_ACTIVITY_EVENT_LAST; i++) {
        gLastEventTime[i] = LLONG_MIN;
    }
    gScreenOn = true;

    gScreenBright = true;

    //初始化驱动接口函数

    gPowerManagerServiceObj = NULL;
    gPowerModule = NULL;
    return 0;

}

//具体实注册的现函数

android_media_MediaDrm.cpp

#define GET_METHOD_ID(var, clazz, fieldName, fieldDescriptor) \
    var = env->GetMethodID(clazz, fieldName, fieldDescriptor); \
    LOG_FATAL_IF(! var, "Unable to find method " fieldName);

//回调函数的实现

PowerManagerService.java

    // Called from native code.
    private void wakeUpFromNative(long eventTime) {
        wakeUpInternal(eventTime);
    }

总结:通过在JNI层注册JAVA层的函数,来实现JNI层到JAVA层的函数调用。

2.2、JAVA层到JAVA层

DisplayPowerController.java

//回调函数接口声明

    /**
     * Asynchronous callbacks from the power controller to the power manager service.
     */
    public interface Callbacks {
        void onStateChanged();
        void onProximityPositive();
        void onProximityNegative();
    }

//触发回调函数,调用实现对象的方法

    private void sendOnStateChangedWithWakelock() {
        mDisplaySuspendBlocker.acquire();
        mCallbackHandler.post(mOnStateChangedRunnable);
    }

    private final Runnable mOnStateChangedRunnable = new Runnable() {
        @Override
        public void run() {
            mCallbacks.onStateChanged();
            mDisplaySuspendBlocker.release();
        }
    };

//回调函数接口实现

PowerManagerService.java

    private final DisplayPowerController.Callbacks mDisplayPowerControllerCallbacks =
            new DisplayPowerController.Callbacks() {
        @Override
        public void onStateChanged() {
            synchronized (mLock) {
                mDirty |= DIRTY_ACTUAL_DISPLAY_POWER_STATE_UPDATED;
                updatePowerStateLocked();
            }
        }

        @Override
        public void onProximityPositive() {
            synchronized (mLock) {
                mProximityPositive = true;
                mDirty |= DIRTY_PROXIMITY_POSITIVE;
                updatePowerStateLocked();
            }
        }

        @Override
        public void onProximityNegative() {
            synchronized (mLock) {
                mProximityPositive = false;
                mDirty |= DIRTY_PROXIMITY_POSITIVE;
                userActivityNoUpdateLocked(SystemClock.uptimeMillis(),
                        PowerManager.USER_ACTIVITY_EVENT_OTHER, 0, Process.SYSTEM_UID);
                updatePowerStateLocked();
            }
        }
    };

//将回调对象作为参数传递给被调用对象

    // The display power controller runs on the power manager service's
    // own handler thread to ensure timely operation.
    mDisplayPowerController = new DisplayPowerController(mHandler.getLooper(),
                    mContext, mNotifier, mLightsService, twilight, sensorManager,
                    mDisplayManagerService, mDisplaySuspendBlocker, mDisplayBlanker,

                    mDisplayPowerControllerCallbacks, mHandler);

总结:通过在被调用类中声明回调函数/对象,并在调用类中实现回调函数/对象,来实现通知调用类的目的。

抱歉!评论已关闭.