监听系统属性SystemProperties值变化
基于 Android-S
一、实现逻辑
相关文件:
frameworks/native/libs/binder/Binder.cpp
/system/core/libutils/misc.cpp
/android/frameworks/base/core/java/android/os/SystemProperties.java
/android/frameworks/base/core/jni/android_os_SystemProperties.cpp
/android/frameworks/base/core/jni/android_util_Binder.cpp
1. callback注册:
private static final ArrayList<Runnable> sChangeCallbacks = new ArrayList<Runnable>(); //SystemProperties.java
static Vector<sysprop_change_callback_info>* gSyspropList = nullptr; //misc.c
addChangeCallback(Runnable callback) //SystemProperties.java public static的 native_add_change_callback() //只对首个callback的注册执行,注意没有传任何参数 ##### SystemProperties_add_change_callback(JNIEnv *env, jobject clazz) //android_os_SystemProperties.cpp sCallChangeCallbacks = env->GetStaticMethodID(sClazz, "callChangeCallbacks", "()V"); //记录java函数的id add_sysprop_change_callback(do_report_sysprop_change, -10000); //形参(cb, priority) sysprop_change_callback_info info; info.callback = cb; //固定是 do_report_sysprop_change() info.priority = priority; bool added = false; for (size_t i=0; i<gSyspropList->size(); i++) { //(只有首个才会)插入到全局vector gSyspropList 中 if (priority >= gSyspropList->itemAt(i).priority) { gSyspropList->insertAt(info, i); //priority数值大的插入在前面 added = true; break; } } if (!added) { gSyspropList->add(info); //优先级数值最小的插入在末尾 } sChangeCallbacks.add(callback) //SystemProperties.java 添加到 ArrayList<Runnable> 链表中
2. 服务端响应,调用回调:
onTransact() //android_util_Binder.cpp if (code == SYSPROPS_TRANSACTION) 成立才调用 BBinder::onTransact() //Binder.cpp case SYSPROPS_TRANSACTION: report_sysprop_change() //misc.cpp do_report_sysprop_change //android_os_SystemProperties.cpp 使用的是namespace Android里面的函数 【1】 env->CallStaticVoidMethod(sClazz, sCallChangeCallbacks); //native回调Java函数 callChangeCallbacks() //SystemProperties.java 看下面首个注册,是这个函数 ArrayList<Runnable> callbacks = new ArrayList<Runnable>(sChangeCallbacks); for (int i = 0; i < callbacks.size(); i++) { callbacks.get(i).run(); //直接调用Runnable类的run()方法,相当于在本线程中执行 } get_report_sysprop_change_func() //misc.cpp do_report_sysprop_change //misc.cpp 通过dlopen(libutils.so)获取的,它本身也属于这个库。 Vector<sysprop_change_callback_info> listeners = *gSyspropList; //每个进程首个插入callback时会添加到这里来 for (size_t i=0; i<listeners.size(); i++) { listeners[i].callback(); do_report_sysprop_change() //android_os_SystemProperties.cpp callback只有一个,固定为它,它的执行内容就是【1】 }
TODO: 【1】为啥会重复执行呢?是不同的内容执行的不一样吗?
3. 客户端调用,使用服务:
/android/frameworks/base/packages/SettingsLib/src/com/android/settingslib/development/SystemPropPoker.java
SystemPropPoker.poke() //这个是通知所有有名服务 createPokerTask().execute() doInBackground(Void... params) String[] services = listServices(); //对系统中的每一个有名服务都调用(你也可以单独调用某一个服务的)######## for (String service : services) { IBinder obj = checkService(service); obj.transact(IBinder.SYSPROPS_TRANSACTION, data, null, 0) }
触发所有有名服务注册的callback回调。
二、其它使用位置
1. ANRdaemon
main(int argc, char* argv[]) start() //ANRdaemon.cpp dfs_poke_binder() //ANRdaemon.cpp sp<IServiceManager> sm = defaultServiceManager(); Vector<String16> services = sm->listServices(); for (size_t i = 0; i < services.size(); i++) { sp<IBinder> obj = sm->checkService(services[i]); if (obj != NULL) { Parcel data; obj->transact(IBinder::SYSPROPS_TRANSACTION, data, NULL, 0); } }
编译成 anrd 这个可执行文件,一般不集成。
三、总结
高负载下此调用会导致SS的绝大多数binder线程被卡住。
参考:
监听SystemProperties变化: https://blog.csdn.net/m0_52481422/article/details/109776370
posted on 2024-11-01 22:08 Hello-World3 阅读(18) 评论(0) 编辑 收藏 举报