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);
总结:通过在被调用类中声明回调函数/对象,并在调用类中实现回调函数/对象,来实现通知调用类的目的。