1.背景概述
众所周知,在安卓系统中有状态栏,在插入外设的时候,会在顶部状态栏显示小图标。
比如,camera设备,耳机设备,U盘,以及电池等等。这些都需要在状态栏动态显示。
从上面这张图片可以看出这些设备都有自己的服务一直在跑,并且都是继承了UEventObserver.java这个类去获取kernel的Event事件。下面将着重分析UEventObserver是如何去监听kernel的Event事件。
2.源码分析
(A)Java层源码分析
//frameworks/base/core/java/android/os/UEventObserver.java
/*
UEventObserver是一个从内核接收UEvents的抽象类。
子类UEventObserver实现onUEvent(UEvent事件),调用startObserving()与匹配字符串匹配,
然后UEvent线程将调用onUEvent()方法,调用stopObserving()停止接收UE事件。
每个进程只有一个UEvent线程,即使该进程具有多个UEventObserver子类实例。
UEvent线程在以下情况下启动:
在该过程中首次调用startObserving()。一旦已启动UEvent线程不会停止(尽管它可以停止通知UEventObserver通过stopObserving())
//hide
*/
public abstract class UEventObserver {
private static UEventThread sThread;
private static native void nativeSetup();
private static native String nativeWaitForNextEvent();
private static native void nativeAddMatch(String match);
private static native void nativeRemoveMatch(String match);
private static UEventThread getThread() {
synchronized (UEventObserver.class) {
if (sThread == null) {
sThread = new UEventThread();
sThread.start();
}
return sThread;
}
}
private static UEventThread peekThread() {
synchronized (UEventObserver.class) {
return sThread;
}
}
//注释监听Observer
public final void startObserving(String match) {
if (match == null || match.isEmpty()) {
throw new IllegalArgumentException("match substring must be non-empty");
}
final UEventThread t = getThread();
t.addObserver(match, this);
}
//停止监听Observer
public final void stopObserving() {
final UEventThread t = peekThread();
if (t != null) {
t.removeObserver(this);
}
}
public abstract void onUEvent(UEvent event);
接下来看一下其使用的UEventThread。
private static final class UEventThread extends Thread {
/** Many to many mapping of string match to observer.
* Multimap would be better, but not available in android, so use
* an ArrayList where even elements are the String match and odd
* elements the corresponding UEventObserver observer */
private final ArrayList<Object> mKeysAndObservers = new ArrayList<Object>();
private final ArrayList<UEventObserver> mTempObserversToSignal =
new ArrayList<UEventObserver>();
public UEventThread() {
super("UEventObserver");
}
@Override
public void run() {
nativeSetup(); //jni调用nativeSetup
while (true) {
String message = nativeWaitForNextEvent(); //jni调用nativeWaitForNextEvent
if (message != null) {
if (DEBUG) {
Log.d(TAG, message);
}
sendEvent(message);
}
}
}
private void sendEvent(String message) {
synchronized (mKeysAndObservers) {
final int N = mKeysAndObservers.size();
for (int i = 0; i < N; i += 2) {
final String key = (String)mKeysAndObservers.get(i);
if (message.contains(key)) {
final UEventObserver observer =
(UEventObserver)mKeysAndObservers.get(i + 1);
mTempObserversToSignal.add(observer);
}
}
}
if (!mTempObserversToSignal.isEmpty()) {
final UEvent event = new UEvent(message);
final int N = mTempObserversToSignal.size();
for (int i = 0; i < N; i++) {
final UEventObserver observer = mTempObserversToSignal.get(i);
observer.onUEvent(event);
}
mTempObserversToSignal.clear();
}
}
public void addObserver(String match, UEventObserver obse