众所周知,在安卓系统中有状态栏,在插入外设的时候,会在顶部状态栏显示小图标。
比如,camera设备,耳机设备,U盘,以及电池等等。这些都需要在状态栏动态显示。
从上面这张图片可以看出这些设备都有自己的服务一直在跑,并且都是继承了UEventObserver.java这个类去获取kernel的Event事件。下面将着重分析UEventObserver是如何去监听kernel的Event事件。
(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
文章浏览阅读55次。敏捷实施在东欧与美国、西欧之间的差距越来越小了。Scrum成为最普遍的框架,Kanban的实施也在增加,并且SAFE、LeSS和DAD也正在流行。在东欧,公司过渡到敏捷的方式非常不同。\\从对Kirill Klimov的采访中得出了如下的一些结论,Kirill Klimov正在参与组织2015东欧敏捷大会。大会将在3月27日-28日的乌克兰基辅举行。\\东欧敏捷大会(AgileEE)的目标描述如下...
文章浏览阅读104次。通过以下方式可以自定义CS类文件代码模板(以下为VS2010,VS2008类似):1,打开VS的安装目录,例如D:\ProgramFiles\MicrosoftVisualStudio10.0\Common7\IDE\ItemTemplates\CSharp\Code\20522,打开文件 Class.zip,找到文件 Class.cs,在文件头部加上下面的内容:#reg..._vs 版权模板
文章浏览阅读551次,点赞6次,收藏18次。1.背景介绍随着互联网的不断发展和人工智能技术的不断进步,我们的软件系统需求也越来越高,同时也变得越来越复杂。为了确保系统的稳定性、性能和安全性,我们需要对系统进行压力测试。压力测试是一种重要的性能测试方法,它可以帮助我们了解系统在高负载下的表现,从而为系统的优化和升级提供有力支持。本文将从以下几个方面来讨论压力测试的方法和策略:背景介绍核心概念与联系核心算法原理和具体操作步骤以...
文章浏览阅读1w次,点赞19次,收藏152次。本文首先讲解遗传算法原理,然后通过python简单演绎下遗传算法原理,最后讲解python中的遗传算法工具包。_遗传算法原理及其 python 实现 csdn
文章浏览阅读56次。1.acunetixwebvulnerabilityScanner4简称AC42.另外以下一种方式走的通,就不用往下走了3.个人爱好用Portready,是因为他快速准确,当然你也可以用别的.4.AC4扫描很耗时间,扫一个网站大约需要3-5个小时,扫整个网段大约需要8个小时左右方法:1.X-SCAN扫描目标服务器(一般是没有漏洞,收集信息用吧),看看IIS写..._完整的博客思路
文章浏览阅读128次。管理员模块:个人中心、用户管理、商家管理、停车场信息管理、预约停车管理、取消预约管理、收费管理、进场停车管理。用户:查看停车场信息、预约和取消预约停车、进场和出场、支付和留言。_停车收费小程序源码
文章浏览阅读883次。解决MAC下xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)的问题_mac error: failed to launch process /library/developer/commandlinetools/libr
文章浏览阅读226次。删除工作空间的一些功能包,每次打开终端提示【rospack】Error:package ‘XXX’not found.解决方法:删除【workspace】/devel/etc/catkin/profile.d 下对应的文件,然后重新编译或重启。_rospack 更新
文章浏览阅读887次。转:http://www.cnblogs.com/jiayy/p/4305018.html前面分析的adbi框架和libinject都是使用so注入的方式,实现将指定代码装入目标进程,这种方式有几个特点:1. 是动态的,需要目标进程已经启动2. 无法影响全局,比如注入A进程挂钩里边libc.so的open函数,此时,B进程使用的libc.so的open函数还是老函数,linux系统通过COW机制,..._android 避免xposed注入
文章浏览阅读3.4k次,点赞6次,收藏12次。react react-router-dom v6 过渡动画_router6怎么写动画
文章浏览阅读1.6k次,点赞16次,收藏24次。以太网通常指的是一种计算机网络技术,用于在局域网(LAN)中传输数据。它最初由英特尔、DEC(Digital Equipment Corporation)和Xerox等公司在20世纪70年代末和80年代初共同开发,并于1980年代晚期和1990年代初期广泛应用于企业和家庭网络中。以太网技术本身的规范,这些规范定义了如何在局域网中传输数据帧(Frames)。它通常使用双绞线、光纤或同轴电缆等物理介质进行数据传输。此外,以太网也涉及一系列的协议和标准,如。_以太网
该文章介绍了柔性作业车间调度问题和CPLEX软件的基本概念,着重讨论了如何利用CPLEX求解柔性作业车间调度问题。文章提到了建立正确的模型,以便在CPLEX中编写代码。