跨进程高级玩法方案2-学员分享

【科学文献计量】标准参考出版年谱(Standard RPYS)和多维参考出版年谱(Multi RPYS) @[TOC](标准参考出版年谱(Standard RPYS)和多维参考出版年谱(Multi RPYS)) 1 标准参考出版年谱与多维参考出版年谱 1.1 标准参考出版年谱(Standard RPYS) 标准参考出版年谱(Standard Reference Publication Year Spectroscopy)是由Marx, Bornmann, Barth, and Leydesdorff(2014)和Marx and Bornmann(2014)提出的一种量化历史出版物对研究领域影响的方法。该方法通 阅读详情

背景:

针对想要在native进程中如何访问systemserver中的display这个java服务
在这里插入图片描述

上一篇文章已经分享了相关的方案
binder跨进程高阶玩法-纯native客户端如何访问java服务端接口

这个方案优劣势如下:
优点:实现原理简单,可以只需要进行代码编写,组装好parcel然后调用transact方法既可以实现跨进程调用,完全不需要依赖其他aidl等模块

缺点:需要针对每个跨进程的接口进行详细的细分,特别是组装和拆装parcel对象,这个每个接口都不一样,而且也比较容易出错

那么基于上面的一个缺点导致的痛点问题,就有学员朋友提出了另一种使用aidl文件的方案来解决这个问题。

方案2实战实现

这里直接上相关的代码,大家可以就可以很容易看出他的方案核心

get_display_ids$ tree
.
├── aidl
│   └── android
│       └── hardware
│           └── display
│               ├── DisplayInfo.aidl
│               └── IDisplayManager.aidl
├── Android.bp
└── src
    ├── DisplayBase.cpp
    ├── DisplayBase.h
    └── main1.cpp

5 directories, 6 files

明显可以看到这里多了两个aidl文件,最熟悉的其实就是 IDisplayManager.aidl,这里是不是看到这个aidl文件,大家大概就可以看出这里实际上就是在native层面使用aidl文件编译生成的c++相关接口,不过这种方式我们前面也聊过因为IDisplayManager.aidl可能依赖较多,aidl单独编译需要引入的aidl也可能会很多,这种引入就会比较麻烦。具体可以看看aidl文件详细情况。

IDisplayManager.aidl

package android.hardware.display;

import android.hardware.display.DisplayInfo;

/** @hide */
interface IDisplayManager {
    @UnsupportedAppUsage
    DisplayInfo getDisplayInfo(int displayId);
    int[] getDisplayIds(boolean includeDisabled);
}

DisplayInfo.aidl --这里可以看出的它主要是依赖"DisplayBase.h"这个头文件来声明相关的结构

package android.hardware.display;

parcelable DisplayInfo cpp_header "DisplayBase.h";


大家明显可以看到这里的IDisplayManager.aidl文件被缩减成了只有两个方法,其实这个IDisplayManager.aidl文件属于原生系统的阉割版本,但是因为我们的需求就是获取的getDisplayIds,DisplayInfo.aidl是因为第一个接口getDisplayInfo需要的一个依赖,所以这个阉割的aidl也是完全可以满足的。

详细源码:
Android.bp

filegroup {
    name: "libdms_client_aidl",
    srcs: [
        "aidl/**/*.aidl"
    ],
    path: "aidl"
}

cc_library {
    name: "libdms_client",
    srcs: [ 
        "src/DisplayBase.cpp",
        ":libdms_client_aidl"
    ],
    aidl: {
        export_aidl_headers: true,
        local_include_dirs: ["aidl"],
    },
    export_include_dirs: [
        "src",
    ],
    shared_libs: [
        "libbinder",
        "liblog",
        "libutils",
    ],
}

cc_binary {
    name: "get_display_ids",
    srcs: [ "src/main1.cpp"],
    shared_libs: [
        "libbinder",
        "liblog",
        "libutils",
        "libdms_client",
    ],
}

这里注意一下编译会有两个目标,一个是libdms_client.so和get_display_ids这个可执行文件。

main1.cpp这个是主要的调用

#include <android/hardware/display/IDisplayManager.h>
#include <binder/IServiceManager.h>
#include <binder/Status.h>
#include <utils/String16.h>
#include <utils/Errors.h>
#include <binder/IInterface.h>
#include <stdio.h>
#include <vector>

using namespace android;

int main() {
    printf("get_display_ids\n");
    auto sm = defaultServiceManager();
    if (sm && sm->checkService(String16("display"))) {
        printf("display service is found\n");
        auto binder = sm->getService(String16("display"));
        auto display = interface_cast<android::hardware::display::IDisplayManager>(binder);
        std::vector<int32_t> ids;
        auto res = display->getDisplayIds(true, &ids);
        if (res.isOk()) {
            printf("ids.size=%d\n", (int)ids.size());
            for (int i =0;i <  (int)ids.size();i++) {
                printf("id[%d]=%d\n",i, ids[i]);
            }
        }
        for(int i = 0;i < ids.size();i++) {
              android::hardware::display::DisplayInfo displayInfo;
		res = display->getDisplayInfo(ids[i], &displayInfo);
		if (res.isOk()) {
		    printf("layerStack=%d\n", displayInfo.layerStack);
		    printf("flags=%d\n", displayInfo.flags);
		    printf("type=%d\n", displayInfo.type);
		    printf("displayId=%d\n", displayInfo.displayId);
		    printf("dispalyGroupId=%d\n", displayInfo.displayGroupId);
		    printf("physicalDisplayId=%d\n", (int)(displayInfo.physicalDisplayId & 0xFF));
		}
		printf("################################################################### \n");
        }
  
    }
    return 0;
}

DisplayBase.h

#include <binder/Parcelable.h>
#include <binder/Parcel.h>
#include <utils/String16.h>


namespace android {
namespace hardware {
namespace display {

struct DisplayInfo : public android::Parcelable {
    int layerStack;
    int flags;
    int type;
    int displayId;
    int displayGroupId;
    //DisplayAddress address;
    int64_t physicalDisplayId;
    //DeviceProductInfo deviceProductInfo;
    String16 deviceProductInfoName;
    String16 manufacturerPnpId;
    String16 productId;
    int32_t modelYear;
    int32_t week;
    int32_t year;
    String16 name;
    int width;
    int height;

    status_t writeToParcel(Parcel * parcel) const;
    status_t readFromParcel(const Parcel * source);
};

}
}
}

DisplayBase.cpp --主要是针对DisplayInfo对象进行parcel包相关的拆装工作

#include "DisplayBase.h"

namespace android {
namespace hardware {
namespace display {
status_t DisplayInfo::writeToParcel(Parcel * parcel) const {
    parcel->writeInt32(layerStack);
    return OK;
}

status_t DisplayInfo::readFromParcel(const Parcel * source) {
    //status_t res = OK;
    layerStack = source->readInt32();
    flags = source->readInt32();
    type = source->readInt32();
    displayId = source->readInt32();
    displayGroupId = source->readInt32();
    physicalDisplayId = source->readInt64();
    deviceProductInfoName = source->readString16();
    manufacturerPnpId = source->readString16();
    productId = source->readString16();
    modelYear = source->readInt32();
    week = source->readInt32();
    year = source->readInt32();
    name = source->readString16();
    width = source->readInt32();
    height = source->readInt32();
    return OK;
}

}// display
}// hardware
}// android

实战结果:

NX563J:/ # get_display_ids                                                                                                                                                                                        
get_display_ids
display service is found
ids.size=2
id[0]=0
id[1]=2 
layerStack=0
flags=16515
type=1
displayId=0
dispalyGroupId=0
physicalDisplayId=36
################################################################### 
layerStack=2
flags=136
type=4
displayId=2
dispalyGroupId=0
physicalDisplayId=255
################################################################### 


可以看到这里的displayId也是正常获取了,一共2个display分别id如下:
id[0]=0
id[1]=2

但是大家是否有发现,使用getDisplayInfo接口其实获取的数据是有问题的,明显就是physicalDisplayId=36是不对的,这里就就相当于留给大家的作业了,大家看看是啥问题,把他修改好后,找马哥确认一下修改方案是ok。

华为OD机试 - 统计文本数量(Java 2025 A卷 100分) 华为OD机试 2025A卷题库疯狂收录中,刷题。 阅读详情

相关推荐

RK3568 解决MIPI屏幕开机只显示uboot logo的问题

之前写过一篇文章介绍了RK3568驱动MIPI屏幕的方法,这次产品迭代,硬件改版,选型的新的屏幕了。所以再次开启调试屏幕的过程。本以为会和上次一样会轻车熟路,事情总是事与愿违,同样的路,遇到新的坑。

fhqlongteng的博客 5427

安卓java端service如何在native进程进行访问-跨进程通讯高端知识

因为跨进程通讯本质上都是需要通过native端,虽然服务端或者客户端是java端,那都是先经过了native端再jni调用到java的,所以完全是可以实现客户端和服务端不要求两个都属于native或者java,完全可以native和java互通。代码1处的intTRANSACTION_getDisplayIds=2,注意这里的2就是从aidl对应的java文件中获得的,所有这个就是为啥要一定要找一个aidl文件生成的参考代码。,相信大家只要实战过马哥跨进程通讯课程肯定就对这个题目有自己的思路和方案。

learnframework的博客 1413

使用GitLab+Drone CI持续集成自动部署web项目,图文详细

kind: pipeline # 定义对象类型,还有secret和signature两种类型 type: docker # 定义流水线类型,还有kubernetes、exec、ssh等类型 name: mall-tiny-drone # 定义流水线名称 steps: # 定义流水线执行步骤,这些步骤将顺序执行 - name: package # 流水线名称 image: maven:3-jdk-8 # 定义创建容器的Docker镜像 volumes: # 将容器内目录挂载到宿主机,仓库

4106

千里马Android Framework实战开发-跨进程通信专题博客总结

千里马Android Framework实战开发-跨进程通信专题课表介绍 因为课程还剩下最后一部分binder驱动没有讲完,但是粉丝同学们已经迫不及待想要要提前看,这里就先分享一个课表给大家,提醒一下,课表的很大,你忍一下。。。。。 预计一星期左右可以上线全部视频,大家敬请期待课程杀青 ...

learnframework的博客 4284

10-142 6-4 查询厂商“D“生产的PC和便携式电脑的平均价格

分数 10全屏浏览题目切换布局作者 lhm单位 河北农业大学本题目要求编写SQL语句,查询厂商D生产的PC和便携式电脑的平均价格。

dqd66的博客 2750

SP贴图高效导入Maya:从材质设置到渲染优化的完整流程

本文详细解析了将Substance Painter(SP)贴图高效导入Maya并配合Arnold渲染器的完整工作流。针对SP贴图在Maya中常见的色彩、法线等问题,核心在于对齐两者的PBR“语言”,重点讲解了SP中正确的贴图导出设置(包括色彩空间)以及在Maya中连接aiStandardSurface材质、处理法线贴图、优化渲染的标准化流程,确保材质效果准确无误。

weixin_29201933的博客 556

某学员framework的闭关学习2个月的过程分享

不过最后发现这个层级结构树要是懂了,也可以画出来后,学习wms后面的东西真舒服,他就像是一个重要理论基础,其他的所有窗口相关的操作都是在这个层级结构树上挂新的节点,换节点,去除节点等操作,还有就是窗口结构树要和SurfaceFlinger结构树要进行结合学习,也理解他们区分等。后来学了这课程后发现确实难得的实战项目干货,刚好把wms课程中学习的wms,sf层级结构树,Winscope分析闪黑等疑难问题,input专题等相关知识进行了综合实战,我更觉得这个是马哥故意给我们添加的实战项目作业题目。

learnframework的博客 1601

CPG控制网络入门

从线性变换开始推导

妖米的博客 5044

千里马framework学习跨进程实战课程学员疑问解答:ClassNotFoundException when unmarshalling

hi,粉丝朋友们!

learnframework的博客 1552

锂电池寿命预测 | Pytorch实现基于Transformer 的锂电池寿命预测(NASA数据集)

锂电池寿命预测 | Pytorch实现基于Transformer 的锂电池寿命预测(NASA数据集)

算法如诗的博客 5588

43_AI短片实战第十六弹:AIGC补充特写镜头——首尾帧衔接与多图抽卡技巧

本文介绍了使用Templa AI平台生成"怪兽爬车"特写镜头并衔接"甩尾摔下"动作的完整流程。首先通过AI生成4张怪兽趴在车顶的特写画面,重点选择展示怪兽与车顶关系的构图(16:9比例)。然后将选定的首帧图与已有尾帧图输入AI,生成7秒左右的过渡视频,实现从"稳定趴车"到"开始摔落"的自然衔接。整个过程展示了单图抽卡策略、首尾帧选择标准,以及如何利用AI生成时间进行其他剪辑任务的并行处理方法。最终产出包括特写首帧图、过渡视频文件和更新后的剪辑项目。

Open 80

Android跨进程通信Client Crash后Server端onDestroy

hi,粉丝朋友大家好!好久没有给大家写blog了,哈哈,这里说声抱歉!实在家里比较忙,今天就来给大家分享一个跨进程专题课中学员问的一个问题,blog就来解答一下这个问题。

learnframework的博客 1365

6.8 点云相关软件——CoProcess

摘要 CoProcess是华测导航研发的三维点云全流程处理平台,支持海量数据浏览、编辑及多类型成果输出,适配地形测绘、道路建设等行业需求。软件采用模块化设计,包含基础功能(数据导入、分类、建模等)和行业定制模块(地形、道路、矿山等),支持多格式数据交互与自动化处理,显著提升作业效率。相比Lidar360,CoProcess操作更简便、性价比更高;相比开源工具CloudCompare,其行业适配性与专业功能更优。2025版本优化了数据处理性能与智能算法,需授权激活高级功能,适合商业项目应用。

qq625924821的博客 248

systemserver为啥很少同步跨进程调用app/DeadSystemException相关问题分析套路

基于上面分析那就基本上明白了导致系统死锁的直接原因,那就是因为systemserver发起了个同步的跨进程调用,这个跨进程调用半天没有得到对方回应,导致systemserver一直卡在这个同步调用这里。

liaosongmao1的专栏 696

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

安卓系统fw工程师面试福利9:近期收集学员手机车载FW面试真题

3、看你这边说了解protolog和各种log调试方式,请问你工作中一般怎么看log,main,events,system,kernel,protolog日志分别代表什么,可否详细说说具体场景,及你从这些log中有什么启发,如果要你为某个模块设计详细log你会怎么做。13、看你fw知识面都比较广,而且熟悉程度也还可以,请问你这边对framework知识技能掌握有啥方式方法,你这边如果在未来工作中会很忙,而且framework技术也发现成长有了瓶颈,有啥突破瓶颈想法?你思考过为啥新版本就要有Spy?

learnframework的博客 471

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Android Framework实战开发-Socket让app实现shell命令行执行

Android Framework实战开发-Socket让app实现shell命令行执行 1、项目背景 在android系统开发过程中,经常会有这样一个需求,就是可能需要让自己app执行一个shell脚本,但是目前app的一般方法都是getRumtime exec方式,但是这种方法基本不可能可以实现,因为只有在root的机子上这个方法才可以成功,但是你想想,一般正常的产品可以有root权限么,那是当然不可能可以有的。 但是有客户就是想要在他的app上可以执行对应的shell命令等来动态启动一些脚本等。 那么

learnframework的博客 4795

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

车载手机系统开发面试福利5:安卓framework系统岗位面试题目汇总

上面这些面试题目,各位粉丝学员朋友们,你们都会吗?不会的话请积极留意vip群中的一些优秀师兄弟的回答哈,马哥会对他们的面试答案进行点评。更多framework实战干货,关注下面“千里马学框架”

learnframework的博客 553

Android Framework面试核心:Binder与Handler机制深度解析

Binder机制作为Android跨进程通信的核心技术,其线程池管理与内存引用机制直接影响系统稳定性。通过分析Binder线程池的同步阻塞特性与RemoteCallbackList的自动清理机制,可以解决跨进程回调中的内存泄漏问题。Handler消息队列模型则涉及ThreadLocal存储原理,合理使用HandlerThread与LifecycleObserver能有效避免内存泄漏。这些Framework层核心技术在大厂面试中常以实际架构问题形式考察,如设计跨进程通知系统或分析Native内存泄漏。掌握Bi

weixin_30412167的博客 443

Android Visualizer 实战:把声音画出来

是系统提供的音频效果(AudioEffect)之一。它挂在音频链路上,,把数据回吐给你——画波形、画频谱、做响度表。

Android的专栏 302
上一篇: 安卓java端service如何在native进程进行访问-跨进程通讯高端知识
下一篇: 重学分屏之进入分屏进入动画Splash Screen图层剖析
千里马学框架
博客等级 码龄6年 1万+粉丝 650原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千里马学框架

帮助你了,就请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值