当前位置: 首页 > wzjs >正文

上海专门做网站的公司河南seo网站多少钱

上海专门做网站的公司,河南seo网站多少钱,湖南张家界建设局网站,广州高端网站建设一文讲透AAOS架构,点到为止不藏私 📌 这篇帖子给大家分析下 AAOS和Framework代码的交互 前面的帖子给大家介绍了CarPowerManager模块的基本功能和逻辑代码,今天分享一个在开发中遇到一个问题: 需求如下: 当用户点击屏幕上的"电源"按钮, IVI…

一文讲透AAOS架构,点到为止不藏私
📌 这篇帖子给大家分析下 AAOS和Framework代码的交互

前面的帖子给大家介绍了CarPowerManager模块的基本功能和逻辑代码,今天分享一个在开发中遇到一个问题:

需求如下:

当用户点击屏幕上的"电源"按钮, IVI主机进入息屏状态,关闭了声音输出. 但是触摸屏(TP)不能禁用. 息屏后, 用户点击屏幕的任意位置, 需要退出待机状态,点亮屏幕, 同时,这次屏幕的触摸事件不能触发UI的跳转, 也就是说, 在framework中需要消费掉这次点击事件.

触摸屏事件上报的流程:

触摸事件从 Kernel 传到 Android Framework(如 ViewRootImpl) 的完整流程,涉及 驱动层 → Input 子系统 → InputManager → WindowManager → ViewRootImpl,下面按层级详细说明:

1. Kernel 层(Linux Input 子系统)

触摸事件通过 TP 驱动(一般是 I2C/SPI)注册为 /dev/input/eventX。
触发时,驱动调用如下代码,Linux Input 子系统将这些事件写入 /dev/input/eventX,由上层读取。

input_report_abs(dev, ABS_MT_POSITION_X, x);
input_report_abs(dev, ABS_MT_POSITION_Y, y);
input_sync(dev);

2. Native 层:EventHub 和 InputReader(system/server)

💡 模块说明

模块文件位置作用
EventHubInputReader.cpp/EventHub.cpp/dev/input/eventX 读取事件
InputReaderInputReader.cpp解析事件、生成 MotionEvent
InputDispatcherInputDispatcher.cpp将事件派发给目标窗口(Window)

主要流程如下:

  • EventHub 使用 epoll 监听 eventX 设备;

  • 检测到事件后读入数据,传递给 InputReader;

  • InputReader 将原始事件解析为 MotionEvent;

  • InputDispatcher 根据坐标找到目标窗口,派发事件。


3.Java 层:WindowManagerService 和 View 层:

InputDispatcherWindowManagerServiceInputChannelViewRootImplDecorView / ActivityViewGroup.dispatchTouchEvent()View.onTouchEvent()

4. 触摸事件的拦截:

经过上面的流程分析, 我们得知,拦截用户点击屏幕的最佳位置是ViewRootImpl.java 的onInputEvent方法, 该方法的原始代码如下:

public final class ViewRootImpl implements ViewParent,View.AttachInfo.Callbacks, ThreadedRenderer.DrawCallbacks {@Overridepublic void onInputEvent(InputEvent event) {Trace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");List<InputEvent> processedEvents;try {processedEvents =mInputCompatProcessor.processInputEventForCompatibility(event);} finally {Trace.traceEnd(Trace.TRACE_TAG_VIEW);}if (processedEvents != null) {if (processedEvents.isEmpty()) {// InputEvent consumed by mInputCompatProcessorfinishInputEvent(event, true);} else {for (int i = 0; i < processedEvents.size(); i++) {enqueueInputEvent(processedEvents.get(i), this,QueuedInputEvent.FLAG_MODIFIED_FOR_COMPATIBILITY, true);}}} else {// 分发触摸屏事件enqueueInputEvent(event, this, 0, true);}}

拦截事件的位置找到了, 我们在这里添加代码来读取当前的屏幕状态, 如果是息屏状态,则写入需要亮屏的指令,然后把事件的类型改为 MotionEvent.ACTION_CANCEL, 修改后的代码如下:

public void onInputEvent(InputEvent event) {//=== add start// 如果是息屏状态下,点亮屏幕,不处理这次触摸事件int screenState = CarDataManager.getInt(CarPowerManager.CACHE_STATE_URI, CarPowerManager.KEY_SCREEN_STATE);if (event != null && screenState == CarPowerManager.SCREEN_STATE_OFF) {CarDataManager.putInt(CarPowerManager.CACHE_STATE_URI, CarPowerManager.KEY_SCREEN_STATE, CarPowerManager.SCREEN_STATE_ON);// 如果需要亮屏, 把事件类型转为ACTION_CANCEL, 不让APP响应事件.((MotionEvent)event).setAction(MotionEvent.ACTION_CANCEL);}//=== add endTrace.traceBegin(Trace.TRACE_TAG_VIEW, "processInputEventForCompatibility");List<InputEvent> processedEvents;

添加完代码后开始编译framework:

android11.0$ make services framework  framework-minus-apex  javac-check-framework car-frameworks-service framework-res  -j32^C

不好的事情发生了, 编译报错了. 啊! 啊! 啊!

s-apex/android_common/javac/shard14/classes -D out/soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard14/classes && rm -rf "out/soong/.intermediates/frameworks/base/framework-minus-apex/android_common/javac/shard14/srcjars"
frameworks/base/core/java/android/view/ViewRootImpl.java:188: error: package android.car.datacenter does not exist
import android.car.datacenter.CarDataManager;^
frameworks/base/core/java/android/view/ViewRootImpl.java:189: error: package android.car.hardware.power does not exist
import android.car.hardware.power.CarPowerManager;^
2 errors
15:23:30 ninja failed with: exit status 1#### failed to build some targets (02:10 (mm:ss)) ####

报错信息显示,ViewRootImpl中import的包不存在,代码明明是存在的, 为啥会引用不到呢???

尝试1:

既然是ViewRootImpl中依赖了car-lib中的代码, 编译引用不到, 是不是在android11.0/frameworks/base/Android.bp的依赖文件中没有添加car-lib的jar包呢?

碰到问题不可怕,冷静下来想方法!!!

报错显示找不到包, 那么我给你指定下包在哪是不是就行了?
马上行动, AOSP 编译的时候,在打包framework.jar时, 会指定很多的三方jar文件,配置如下:

// Collection of classes that are generated from non-Java files that are not listed in
// framework_srcs. These have no or very limited dependency to the framework.
java_library {name: "framework-internal-utils",static_libs: ["apex_aidl_interface-java","suspend_control_aidl_interface-java","framework-protos","game-driver-protos","android.hidl.base-V1.0-java","android.hardware.cas-V1.0-java","android.hardware.cas-V1.1-java","android.hardware.cas-V1.2-java","android.hardware.contexthub-V1.0-java","android.hardware.contexthub-V1.1-java","android.hardware.gnss-V1.0-java","android.hardware.gnss-V2.1-java","android.hardware.health-V1.0-java-constants","android.hardware.radio-V1.0-java","android.hardware.radio-V1.1-java","android.hardware.radio-V1.2-java","android.hardware.radio-V1.3-java","android.hardware.radio-V1.4-java","android.hardware.radio-V1.5-java","android.hardware.thermal-V1.0-java-constants","android.hardware.thermal-V1.0-java","android.hardware.thermal-V1.1-java","android.hardware.thermal-V2.0-java","android.hardware.tv.input-V1.0-java-constants","android.hardware.tv.tuner-V1.0-java-constants","android.hardware.usb-V1.0-java-constants","android.hardware.usb-V1.1-java-constants","android.hardware.usb-V1.2-java-constants","android.hardware.usb.gadget-V1.0-java","android.hardware.vibrator-V1.0-java","android.hardware.vibrator-V1.1-java","android.hardware.vibrator-V1.2-java","android.hardware.vibrator-V1.3-java","devicepolicyprotosnano",

把car-lib加入到依赖的jar包路径,修改如下:

        "android.hardware.vibrator-V1.2-java","android.hardware.vibrator-V1.3-java","devicepolicyprotosnano", // 注意这个后面的",""android.car"

这里补充一句, 如何去查找CarPowerManager所在的jar包呢?

CarPowerManager的源码路径如下:

android11.0\packages\services\Car\car-lib\src\android\car\hardware\power\CarPowerManager.java

car-lib的编译脚本如下:

android11.0\packages\services\Car\car-lib\Android.bp
java_library {name: "android.car", // 编译的输入物srcs: ["src/**/*.java","src/**/I*.aidl",],aidl: {include_dirs: ["system/bt/binder",],},exclude_srcs: ["src/android/car/storagemonitoring/IoStats.aidl","src/android/car/storagemonitoring/IoStatsEntry.aidl",],static_libs: ["android.car.internal.event-log-tags",],product_variables: {pdk: {enabled: false,},},installable: true,
}

从编译脚本可见,编译后的输出物为android.car


满心欢喜,继续…
不出意外的话, 必然有意外.
又报另外一个错误, 信息如下:

[hardware/rockchip/libgralloc/bifrost frameworks/native/include system/core/libsync system/core/libsync/include external/libdrm/include/drm] 30
>>>>>>>>>>>>>>>>>>>>> rk356x
libcameradevice curr board is rk356x
error: frameworks/base/Android.bp:479:1: encountered dependency cycle:
error: frameworks/base/Android.bp:518:1:     "framework" depends on "framework-minus-apex"
error: frameworks/base/Android.bp:479:1:     "framework-minus-apex" depends on "framework-internal-utils"
error: frameworks/base/Android.bp:349:1:     "framework-internal-utils" depends on "android.car"
error: packages/services/Car/car-lib/Android.bp:74:1:     "android.car" depends on "framework"
16:19:26 soong bootstrap failed with: exit status 1#### failed to build some targets (16 seconds) ####

又来…
从这个报错信息来看, 是循环引用了:
framework 依赖 framework-minus-apex
framework-minus-apex 依赖 framework-internal-utils
framework-internal-utils 依赖 android.car
android.car 依赖 framework

遇到一个"鸡生蛋, 还是蛋生鸡的问题"…


经过一番折腾后, 发现此路不通, 只得另寻它路.
一番冥思苦想之后, 发现我们的需求是 “在不同的进程间共享状态”, 系统提供了几种进程间共享数据的方式如下:

对比项SystemPropertiesSettings.Global.putInt()广播(Broadcast)
本质内核属性(属性服务)ContentProvider(数据库访问)Binder + Intent 派发
通信方向单向(读/写)单向(读/写)单向或多向(可被多个组件接收)
使用场景轻量级系统配置;开机参数;Boot 动态配置全局配置项(如亮度、音量模式等)通知型事件(如网络变化、电池变化等)
设置权限控制system 权限;部分 key 需 SELinux 配置需系统签名或拥有权限(如 WRITE_SETTINGS)权限控制精细(需定义权限过滤)
读写效率(性能)非常高(C 层实现,几乎无 IO 成本)较慢(写入数据库,有 IO)中等偏慢(Intent 封送+跨进程)
内存占用很小较小中等(Intent 结构体 + 广播记录)
实时性 / 响应速度中等中等偏低(尤其是异步广播)
⛓ 是否支持监听/回调否(仅轮询读取)否(只能主动查询)支持广播接收器监听(动态/静态)
适合用于跨版本或模块通信不推荐(key 容易变动)稳定性较差,schema 不统一推荐,尤其适合解耦模块间传递状态或事件
安全性(信息暴露风险)较低(权限严格)中(视 key 设置而定)需要明确权限设置,广播可能被第三方监听
✅ 是否推荐用于模块解耦通信❌ 不推荐(只做简单配置)❌ 不推荐(更多用于配置项)✅ 推荐(尤其是系统-APP/模块间事件通知)

这三种进程间共享数据的优缺点总结如下:

场景推荐方式
传递轻量状态或只读参数SystemProperties
写入系统设置项(如亮度)Settings.Global
模块间事件通知、状态变更✅ 广播(Broadcast)
高性能低延迟状态读写SystemProperties
需要监听回调✅ 广播

总结:

对于我们当前的场景,在PowerManager中通过SystemProperties.put()把状态保存下来. 在ViewRootImpl中通过SystemProperties.get()这种方式来传递数据.

到此, 问题得到完美的解决.

“专注AAOS架构与实战,欢迎关注一起探索车载开发。”

http://www.dtcms.com/wzjs/8173.html

相关文章:

  • 郑州企业网站建设费用企业网络营销
  • 货源之家官网宁波谷歌seo推广公司
  • 访问网站 流程图营销网站建设软件下载
  • ui是做网站的吗东莞seo网站优化排名
  • 怎么把网站上线长沙网红打卡景点排行榜
  • 衢州企业网站建设公司广州今天新闻
  • 网站建设合同定义域名查询
  • 网络推广及网站建设合作协议seo程序
  • 郑州网站建设案例长春百度快速优化
  • 贵金属网站模板东莞seo项目优化方法
  • 软路由系统如何做网站腾讯企点官网下载
  • 各大网站的软文怎么做站长
  • 怎么做国际网站首页seo推广一年要多少钱
  • 网站建设物美价廉千万别手贱在百度上搜这些词
  • 永嘉网站制作哪家好深圳网络推广的公司
  • 葡萄牙语网站设计哪家好软文范例大全
  • 商业网站建设软件seo搜索引擎优化课程总结
  • 济宁市精神文明建设委员会网站百度推广销售员好做吗
  • 盐山做网站价格惠州优化怎么做seo
  • 网站建设与管理案例教程在线阅读账号权重查询入口
  • php编程软件中文seo零基础教学
  • 天津网站建设方案外包营销活动策划方案
  • 地方网站做相亲赢利点在哪里百度的网址是什么呢
  • 外贸网站推广服务seo网络推广员招聘
  • 成都活动策划公司百家港 seo服务
  • 做地方网站需要什么部门批准营销推广策划及渠道
  • seo网站排名优化软件酒店网络营销方式有哪些
  • wordpress中文 插件下载湖北seo服务
  • 南阳移动端网站制作网站怎么优化搜索
  • 新衡阳网站郑州厉害的seo顾问