一、 Android uevent架构

 

Android很多事件都是通过 uevent kernel来异步通信的。其中类 UEventObserver是核心。 
UEventObserver接收 kernel uevent信息的抽象类。 

1 server层代码 
1)battery server:
frameworks/frameworks/base/services/java/com/android/server/SystemServer.java
frameworks/frameworks/base/services/java/com/android/server/BatteryService.java

2 java层代码 
frameworks/base/core/java/android/os/UEventObserver.java

3 JNI层代码 
frameworks/base/core/jni/android_os_UEventObserver.cpp

4、底层代码 
hardware/libhardware_legacy/uevent/uevent.c
读写 kernel的接口 socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);

二、 UEventObserver的使用


 UEventObserver提供了三个接口给子类来调用: 
1 onUEvent(UEvent event)
子类必须重写这个 onUEvent来处理 uevent 
2 startObserving(String match)
启动进程,要提供一个字符串参数。 
3 stopObserving()
停止进程。 

例子: 
// BatteryService.java

view plain
  1. mUEventObserver.startObserving("SUBSYSTEM=power_supply");  
  2. private UEventObserver mUEventObserver = new UEventObserver() {  
  3. @Override  
  4. public void onUEvent(UEventObserver.UEvent event) {  
  5. update();  
  6. }  
  7. };  

 UEvent thread 中会不停调用 update() 方法,来更新电池的信息数据。

 

三、 vold server分析 

1、在 system/vold/NetlinkManager.cpp中: 

view plain
  1. if ((mSock = socket(PF_NETLINK,SOCK_DGRAM,NETLINK_KOBJECT_UEVENT)) < 0) {  
  2. SLOGE("Unable to create uevent socket: %s", strerror(errno));  
  3. return -1;  
  4. }  
  5. if (setsockopt(mSock, SOL_SOCKET, SO_RCVBUFFORCE, &sz, sizeof(sz)) < 0) {  
  6. SLOGE("Unable to set uevent socket options: %s", strerror(errno));  
  7. return -1;  
  8. }  
  9. if (bind(mSock, (struct sockaddr *) &nladdr, sizeof(nladdr)) < 0) {  
  10. SLOGE("Unable to bind uevent socket: %s", strerror(errno));  
  11. return -1;  
  12. }  


2 、然后在 system/vold/NetlinkHandler.cpp  NetlinkHandler::onEvent 中处理

view plain
  1. void NetlinkHandler::onEvent(NetlinkEvent *evt) {  
  2. VolumeManager *vm = VolumeManager::Instance();  
  3. const char *subsys = evt->getSubsystem();  
  4. if (!subsys) {  
  5. SLOGW("No subsystem found in netlink event");  
  6. return;  
  7. }  
  8. if (!strcmp(subsys, "block")) {  
  9. vm->handleBlockEvent(evt);  
  10. else if (!strcmp(subsys, "switch")) {  
  11. vm->handleSwitchEvent(evt);  
  12. else if (!strcmp(subsys, "battery")) {  
  13. else if (!strcmp(subsys, "power_supply")) {  
  14. }  
  15. }  

3 、在 system/core/libsysutils/src/NetlinkListener.cpp 中监听。 


四、 battery server 分析

 

java代码: 
frameworks/frameworks/base/services/java/com/android/server/BatteryService.java

JNI代码: 
frameworks/base/services/jni/com_android_server_BatteryService.cpp

 

1 BatteryService是跑在 system_process当中,在系统初始化的时候启动,如下 
 BatteryService.java中: 
Log.i(TAG, “Starting Battery Service.”);
BatteryService battery = new BatteryService(context);
ServiceManager.addService(“battery”, battery);

2、数据来源 
BatteryService通过 JNI com_android_server_BatteryService.cpp)读取数据。 
BatteryService通过 JNI注册的不仅有函数,还有变量。 如下:

view plain
  1. //##############在BatteryService.java中声明的变量################  
  2. private boolean mAcOnline;  
  3. private boolean mUsbOnline;  
  4. private int mBatteryStatus;  
  5. private int mBatteryHealth;  
  6. private boolean mBatteryPresent;  
  7. private int mBatteryLevel;  
  8. private int mBatteryVoltage;  
  9. private int mBatteryTemperature;  
  10. private String mBatteryTechnology;  
  11. //在BatteryService.java中声明的变量,在com_android_server_BatteryService.cpp中共  
  12. 用,即在com_android_server_BatteryService.cpp中其实操作的也是BatteryService.java中声  
  13. 明的变量。  
  14. gFieldIds.mAcOnline = env->GetFieldID(clazz, “mAcOnline”, “Z”);  
  15. gFieldIds.mUsbOnline = env->GetFieldID(clazz, “mUsbOnline”, “Z”);  
  16. gFieldIds.mBatteryStatus = env->GetFieldID(clazz, “mBatteryStatus”, “I”);  
  17. gFieldIds.mBatteryHealth = env->GetFieldID(clazz, “mBatteryHealth”, “I”);  
  18. gFieldIds.mBatteryPresent = env->GetFieldID(clazz, “mBatteryPresent”, “Z”);  
  19. gFieldIds.mBatteryLevel = env->GetFieldID(clazz, “mBatteryLevel”, “I”);  
  20. gFieldIds.mBatteryTechnology = env->GetFieldID(clazz, “mBatteryTechnology”,  
  21. “Ljava/lang/String;”);  
  22. gFieldIds.mBatteryVoltage = env->GetFieldID(clazz, “mBatteryVoltage”, “I”);  
  23. gFieldIds.mBatteryTemperature = env->GetFieldID(clazz, “mBatteryTemperature”,  
  24. “I”);  
  25. //上面这些变量的值,对应是从下面的文件中读取的,一只文件存储一个数值。  
  26. #define AC_ONLINE_PATH “/sys/class/power_supply/ac/online”  
  27. #define USB_ONLINE_PATH “/sys/class/power_supply/usb/online”  
  28. #define BATTERY_STATUS_PATH “/sys/class/power_supply/battery/status”  
  29. #define BATTERY_HEALTH_PATH “/sys/class/power_supply/battery/health”  
  30. #define BATTERY_PRESENT_PATH “/sys/class/power_supply/battery/present”  
  31. #define BATTERY_CAPACITY_PATH “/sys/class/power_supply/battery/capacity”  
  32. #define BATTERY_VOLTAGE_PATH “/sys/class/power_supply/battery/batt_vol”  
  33. #define BATTERY_TEMPERATURE_PATH “/sys/class/power_supply/battery/batt_temp”  
  34. #define BATTERY_TECHNOLOGY_PATH “/sys/class/power_supply/battery/technology”  

3、数据传送


BatteryService主动把数据传送给所关心的应用程序,所有的电池的信息数据是通过 Intent传送出去

的。 
 BatteryService.java中, Code如下:

view plain
  1. Intent intent = new Intent(Intent.ACTION_BATTERY_CHANGED);  
  2. intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);  
  3. intent.putExtra(“status”, mBatteryStatus);  
  4. intent.putExtra(“health”, mBatteryHealth);  
  5. intent.putExtra(“present”, mBatteryPresent);  
  6. intent.putExtra(“level”, mBatteryLevel);  
  7. intent.putExtra(“scale”, BATTERY_SCALE);  
  8. intent.putExtra(“icon-small”, icon);  
  9. intent.putExtra(“plugged”, mPlugType);  
  10. intent.putExtra(“voltage”, mBatteryVoltage);  
  11. intent.putExtra(“temperature”, mBatteryTemperature);  
  12. intent.putExtra(“technology”, mBatteryTechnology);  
  13. ActivityManagerNative.broadcastStickyIntent(intent, null);  

 

4、数据接收


应用如果想要接收到 BatteryService发送出来的电池信息, 
则需要注册一个 Intent Intent.ACTION_BATTERY_CHANGED BroadcastReceiver

注册方法如下:

view plain
  1. IntentFilter mIntentFilter = new IntentFilter();  
  2. mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);  
  3. registerReceiver(mIntentReceiver, mIntentFilter);  
  4. private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {  
  5. @Override  
  6. public void onReceive(Context context, Intent intent) {  
  7. // TODO Auto-generated method stub  
  8. String action = intent.getAction();  
  9. if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {  
  10. int nVoltage = intent.getIntExtra(“voltage”, 0);  
  11. if(nVoltage!=0){  
  12. mVoltage.setText(“V: ” + nVoltage + “mV – Success…”);  
  13. }  
  14. else{  
  15. mVoltage.setText(“V: ” + nVoltage + “mV – fail…”);  
  16. }  
  17. }  
  18. }  
  19. };  

5、数据更新


电池的信息会随着时间不停变化,自然地,就需要考虑如何实时的更新电池的数据信息。在

BatteryService启动的时候,会同时通过 UEventObserver启动一个 onUEvent Thread。每一个

Process最多只能有一个 onUEvent Thread,即使这个 Process中有多个 UEventObserver的实例。 
当在一个 Process中,第一次 Call startObserving()方法后,这个 UEvent thread就启动了。 
而一旦这个 UEvent thread启动之后,就不会停止。

 

// BatteryService.java

view plain
  1. mUEventObserver.startObserving(“SUBSYSTEM=power_supply”);  
  2. private UEventObserver mUEventObserver = new UEventObserver() {  
  3. @Override  
  4. public void onUEvent(UEventObserver.UEvent event) {  
  5. update();  
  6. }  
  7. };  

 UEvent thread 中会不停调用 update() 方法,来更新电池的信息数据。

更多相关文章

  1. Android SQLite数据库操作实例
  2. 【Android】Android 联系人数据库浅析之通话记录
  3. mac添加android的adb等工具到环境变量
  4. android 使用Intent传递数据之剪切板
  5. Android 内存数据库
  6. android入门1:有关布局与activity数据传递等
  7. Android联系人数据库全解析(5)
  8. 移动开发:Android数据连接浅析

随机推荐

  1. Android NDK 知识系列(一)
  2. Android NDK编程入门
  3. 学习Android过程中的一些博客或工具收集
  4. Android's HTTP Clients -Android的http
  5. 最近整理的Android学习笔记
  6. 命令行下Android应用开发
  7. 【Android】魅族Flyme OS 3摄像头无法预
  8. Android编译详解之lunch命令
  9. android studio 导入eclipse项目 兼容性
  10. Android中布局属性(如android:drawableBot