Android UEvent事件分析_安卓uevent事件接收-程序员宅基地

技术标签: android  Uevent  linux  

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
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u010664697/article/details/130968009

智能推荐

Kirill Klimov访谈:东欧的敏捷实施现状-程序员宅基地

文章浏览阅读55次。敏捷实施在东欧与美国、西欧之间的差距越来越小了。Scrum成为最普遍的框架,Kanban的实施也在增加,并且SAFE、LeSS和DAD也正在流行。在东欧,公司过渡到敏捷的方式非常不同。\\从对Kirill Klimov的采访中得出了如下的一些结论,Kirill Klimov正在参与组织2015东欧敏捷大会。大会将在3月27日-28日的乌克兰基辅举行。\\东欧敏捷大会(AgileEE)的目标描述如下...

为VS2010默认模板添加版权信息 .-程序员宅基地

文章浏览阅读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.背景介绍随着互联网的不断发展和人工智能技术的不断进步,我们的软件系统需求也越来越高,同时也变得越来越复杂。为了确保系统的稳定性、性能和安全性,我们需要对系统进行压力测试。压力测试是一种重要的性能测试方法,它可以帮助我们了解系统在高负载下的表现,从而为系统的优化和升级提供有力支持。本文将从以下几个方面来讨论压力测试的方法和策略:背景介绍核心概念与联系核心算法原理和具体操作步骤以...

遗传算法原理及其python实现_遗传算法原理及其 python 实现 csdn-程序员宅基地

文章浏览阅读1w次,点赞19次,收藏152次。本文首先讲解遗传算法原理,然后通过python简单演绎下遗传算法原理,最后讲解python中的遗传算法工具包。_遗传算法原理及其 python 实现 csdn

***大站的完整思路-程序员宅基地

文章浏览阅读56次。1.acunetixwebvulnerabilityScanner4简称AC42.另外以下一种方式走的通,就不用往下走了3.个人爱好用Portready,是因为他快速准确,当然你也可以用别的.4.AC4扫描很耗时间,扫一个网站大约需要3-5个小时,扫整个网段大约需要8个小时左右方法:1.X-SCAN扫描目标服务器(一般是没有漏洞,收集信息用吧),看看IIS写..._完整的博客思路

基于微信小程序的停车场预约收费SSM-JAVA【数据库设计、论文、源码、开题报告】_停车收费小程序源码-程序员宅基地

文章浏览阅读128次。管理员模块:个人中心、用户管理、商家管理、停车场信息管理、预约停车管理、取消预约管理、收费管理、进场停车管理。用户:查看停车场信息、预约和取消预约停车、进场和出场、支付和留言。_停车收费小程序源码

随便推点

解决MAC下xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)的问题_mac error: failed to launch process /library/devel-程序员宅基地

文章浏览阅读883次。解决MAC下xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools)的问题_mac error: failed to launch process /library/developer/commandlinetools/libr

ROS的常见问题(不定时更新)_rospack 更新-程序员宅基地

文章浏览阅读226次。删除工作空间的一些功能包,每次打开终端提示【rospack】Error:package ‘XXX’not found.解决方法:删除【workspace】/devel/etc/catkin/profile.d 下对应的文件,然后重新编译或重启。_rospack 更新

Android应用防xposed注入,android hook 框架 xposed 如何实现注入-程序员宅基地

文章浏览阅读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注入

react react-router V6 路由切换实现过渡动画_router6怎么写动画-程序员宅基地

文章浏览阅读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求解agv调度-程序员宅基地

该文章介绍了柔性作业车间调度问题和CPLEX软件的基本概念,着重讨论了如何利用CPLEX求解柔性作业车间调度问题。文章提到了建立正确的模型,以便在CPLEX中编写代码。

推荐文章

热门文章

相关标签