您的位置:首页 > 产品设计 > UI/UE

Android UEventObserver

2015-08-29 11:38 537 查看
UEventObserver是android Java层利用uevent与获取Kernel层状态变化的机制。

通过grep发现framework有如下模块使用UEventObserver的功能来提供服务:
电池状态:services/java/com/android/server/BatteryService.java
耳机状态:services/java/com/android/server/HeadsetObserver.java
DOCK状态:services/java/com/android/server/DockObserver.java
USB状态:services/java/com/android/server/usb/UsbService.java

它们全部继承自UEventObserver,先看看这个类的构造和原理:

./core/java/android/os/UEventObserver.java

                              |

          [ native_setup(), next_event() ]

                             \|/

./core/jni/android_os_UEventObserver.cpp

                              |

          [ uevent_init(),uevent_next_event() ]

                             \|/

/hardware/libhardware_legacy/uevent/uevent.c

                              |                                                                                         [userspace]

---------------------[socket]-----------------------------------------------------------------------------

                              |

                             \|/                                                                                           [kernel]

     socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT)

下面用HeadsetObserver作为例子说明如何使用UEventObserver来监听kernel的uevent。

继承UEventObserver的类必须实现自己的public abstract void onUEvent(UEvent event):

[java] view
plaincopy

@Override  

public void onUEvent(UEventObserver.UEvent event) {  

    if (LOG) Slog.v(TAG, "Headset UEVENT: " + event.toString());  

  

    try {  

        update(event.get("SWITCH_NAME"), Integer.parseInt(event.get("SWITCH_STATE"))); // update中处理事务  

    } catch (NumberFormatException e) {  

        Slog.e(TAG, "Could not parse switch state from event " + event);  

    }  

}  

这个函数会在UEventObserver接收到event的时候由UEventObserver来回调,HeadsetObserver使用startObserving("DEVPATH=/devices/virtual/switch/h2w")来开始监听,这个API会确保sThread已经运行并且以字串参数作为匹配参数增加一个observer:
    public final synchronized void startObserving(String match) {

        ensureThreadStarted();

        sThread.addObserver(match, this);

    }

UEventObserver的核心部分就是sThread的run:

[java] view
plaincopy

public void run() {  

    native_setup(); //调用uevent.c中的API来打开socket  

  

    byte[] buffer = new byte[1024];  

    int len;  

    while (true) {  

        len = next_event(buffer); // 在uevent.c中用poll调用来获取event,会阻塞  

        if (len > 0) {  

            String bufferStr = new String(buffer, 0, len);  // easier to search a String  

            synchronized (mObservers) {  

                for (int i = 0; i < mObservers.size(); i += 2) {  

                    if (bufferStr.indexOf((String)mObservers.get(i)) != -1) { // 找到匹配的match参数,说明某个observer的监听的event发生了  

                        ((UEventObserver)mObservers.get(i+1))  

                                .onUEvent(new UEvent(bufferStr)); // 调用这个observer的onUEvent函数  

                    }  

                }  

            }  

        }  

    }  

}  

// TODO: 分析kernel层如何上报uevent事件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: