一、Android uevent架构

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

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

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

3JNI层代码
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提供了三个接口给子类来调用:
1onUEvent(UEvent event)
子类必须重写这个onUEvent来处理uevent
2startObserving(String match)
启动进程,要提供一个字符串参数。
3stopObserving()
停止进程。

例子:
//BatteryService.java

view plain
  1. mUEventObserver.startObserving("SUBSYSTEM=power_supply");
  2. privateUEventObservermUEventObserver=newUEventObserver(){
  3. @Override
  4. publicvoidonUEvent(UEventObserver.UEventevent){
  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("Unabletocreateueventsocket:%s",strerror(errno));
  3. return-1;
  4. }
  5. if(setsockopt(mSock,SOL_SOCKET,SO_RCVBUFFORCE,&sz,sizeof(sz))<0){
  6. SLOGE("Unabletosetueventsocketoptions:%s",strerror(errno));
  7. return-1;
  8. }
  9. if(bind(mSock,(structsockaddr*)&nladdr,sizeof(nladdr))<0){
  10. SLOGE("Unabletobindueventsocket:%s",strerror(errno));
  11. return-1;
  12. }


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

view plain
  1. voidNetlinkHandler::onEvent(NetlinkEvent*evt){
  2. VolumeManager*vm=VolumeManager::Instance();
  3. constchar*subsys=evt->getSubsystem();
  4. if(!subsys){
  5. SLOGW("Nosubsystemfoundinnetlinkevent");
  6. return;
  7. }
  8. if(!strcmp(subsys,"block")){
  9. vm->handleBlockEvent(evt);
  10. }elseif(!strcmp(subsys,"switch")){
  11. vm->handleSwitchEvent(evt);
  12. }elseif(!strcmp(subsys,"battery")){
  13. }elseif(!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

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

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

view plain
  1. //##############在BatteryService.java中声明的变量################
  2. privatebooleanmAcOnline;
  3. privatebooleanmUsbOnline;
  4. privateintmBatteryStatus;
  5. privateintmBatteryHealth;
  6. privatebooleanmBatteryPresent;
  7. privateintmBatteryLevel;
  8. privateintmBatteryVoltage;
  9. privateintmBatteryTemperature;
  10. privateStringmBatteryTechnology;
  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. #defineAC_ONLINE_PATH“/sys/class/power_supply/ac/online”
  27. #defineUSB_ONLINE_PATH“/sys/class/power_supply/usb/online”
  28. #defineBATTERY_STATUS_PATH“/sys/class/power_supply/battery/status”
  29. #defineBATTERY_HEALTH_PATH“/sys/class/power_supply/battery/health”
  30. #defineBATTERY_PRESENT_PATH“/sys/class/power_supply/battery/present”
  31. #defineBATTERY_CAPACITY_PATH“/sys/class/power_supply/battery/capacity”
  32. #defineBATTERY_VOLTAGE_PATH“/sys/class/power_supply/battery/batt_vol”
  33. #defineBATTERY_TEMPERATURE_PATH“/sys/class/power_supply/battery/batt_temp”
  34. #defineBATTERY_TECHNOLOGY_PATH“/sys/class/power_supply/battery/technology”

3、数据传送


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

的。
BatteryService.java中,Code如下:

view plain
  1. Intentintent=newIntent(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发送出来的电池信息,
则需要注册一个IntentIntent.ACTION_BATTERY_CHANGEDBroadcastReceiver

注册方法如下:

view plain
  1. IntentFiltermIntentFilter=newIntentFilter();
  2. mIntentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
  3. registerReceiver(mIntentReceiver,mIntentFilter);
  4. privateBroadcastReceivermIntentReceiver=newBroadcastReceiver(){
  5. @Override
  6. publicvoidonReceive(Contextcontext,Intentintent){
  7. //TODOAuto-generatedmethodstub
  8. Stringaction=intent.getAction();
  9. if(action.equals(Intent.ACTION_BATTERY_CHANGED)){
  10. intnVoltage=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. privateUEventObservermUEventObserver=newUEventObserver(){
  3. @Override
  4. publicvoidonUEvent(UEventObserver.UEventevent){
  5. update();
  6. }
  7. };

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

更多相关文章

  1. [Android(安卓)Studio] Android(安卓)studio 多渠道打包(超简洁
  2. Android(安卓)基础总结:(四)Activity(InstanceState)
  3. Android(安卓)剪贴板详解
  4. 【Android】数据存储之Files
  5. Android(安卓)jni系统变量、函数、接口定义汇总
  6. android中Content Provider
  7. Android下实现一个手机监控摄像头
  8. 【Android】数据存储之Files
  9. Android中的Adapter

随机推荐

  1. Android箭头图标移动动画实现
  2. Activity布局初步(一)
  3. Android,谁动了我的内存(转)
  4. Android高手进阶教程(二十一)之---Androi
  5. (4.1.15)Android 基础教程之-------Android
  6. android 中style的使用
  7. Android(安卓)FileHelper 打开各种类型文
  8. [置顶] Android开发:在onTouchEvent中处理
  9. Android开发之旅:应用程序基础及组件
  10. android配置总结