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

Android 进阶——Framework核心 之Binder Java成员类详解(三)

文章大纲

  • 引言
  • 一、Binder Java家族核心成员关系图
  • 二、Binder Java家族核心成员源码概述
    • 1、android.os.IBinder
      • 1.1、boolean transact(int code, Parcel data, Parcel reply, int flags) send a call to an IBinder object
      • 1.2、String getInterfaceDescriptor()
      • 1.3、boolean pingBinder() 检测Binder是否存活
      • 1.4、boolean isBinderAlive()检测托管进程是否存在
      • 1.5、 IInterface queryLocalInterface(String descriptor) 获取Binder对应的本地实现对象
      • 1.6、android.os.IBinder.DeathRecipient
      • 1.7、android.os.IBinder 小结
    • 2、android.os.Binder 和 android.os.BinderProxy
      • 2.1、Binder 构造方法
      • 2.2、attachInterface(IInterface owner, String descriptor) 初始化
      • 2.3、boolean onTransact(int code, Parcel data, Parcel reply,
      • 2.4、android.os.BinderProxy
    • 3、android.os.IInterface
    • 4、Stub和Stub.Proxy角色

引言

上一篇文章解读了Binder native家族成员的关系和功能,不过呢,和这篇文章关系也不是很大,不存在先后的顺序,因为这篇文章是主要解读Binder 代码层面主要Java家族成员类功能和部分代码的,目的是从代码和逻辑设计对Binder 有更深的理解。不过呢,Android中Java 、Native层使用同一套架构实现Binder服务,而且Java层最终是通过JNI调用Native 层的实现的,因此可以对照native层学习Java层将更容易掌握,所以建议先看native层的。

一、Binder Java家族核心成员关系图

主要有IBinder、IInterface、 Binder、BinderProxy类和Stub、Stub.Proxy角色。
在这里插入图片描述

  • IBinder接口——代表一种跨进程传输的能力,实现这个接口就能将这个对象进行跨进程传递。
  • Binder类——Binder本地对象。
  • BinderProxy类——代表服务进程的Binder对象的本地代理。
  • Parcel类——主要用于存储序列化数据,然后可以通过Binder在进程间传递这些数据。
  • IInterface接口——Client端与Server端的调用契约(提供什么样的能力),实现这个接口就代表远程Server对象具有什么能力,其asBinder方法可以将Binder本地对象或代理对象返回。
  • Stub角色(Local-side IPC implementation stub class)——是AIDL接口的静态内部抽象类,继承Binder并实现了具体的IInterface派生接口,负责把Binder转为Stup.Proxy角色。
  • Stub.Proxy角色——Binder代理对象,Stub的静态内部类同样实现了AIDL接口派生类,真正去实现Binder#transact方法去实现AIDL接口方法的跨进程通信逻辑。

asInterface方法——当客户端bindService的onServiceConnecttion的回调里面,通过asInterface方法获取远程的service的。其函数的参数IBinder类型的obj,这个对象是驱动给我们的,如果是Binder本地对象,那么它就是Binder类型,如果是Binder代理对象,那就是BinderProxy类型。asInterface方法中会调用queryLocalInterface,查找Binder本地对象,如果找到,说明Client和Server都在同一个进程,这个参数直接就是本地对象,直接强制类型转换然后返回,如果找不到,说明是远程对象那么就需要创建Binder代理对象,让这个Binder代理对象实现对于远程对象的访问首先用Parcel把数据序列化,然后调用mRemote.transact方法,mRemote就是new Stub.Proxy(obj)传进来的,即BinderProxy对象

二、Binder Java家族核心成员源码概述

Framework层的Binder通过JNI来调用(C/C++)层的Binder框架,从而为上层应用程序提供服务。而Java层在命名与架构上和Native也非常相近,基本上是无缝衔接,同样也实现了一套类似的IPC通信架构供应用开发使用,当然最后都是通过Native层的Binder框架实现的。

1、android.os.IBinder

IBinder是远程对象的Base接口,不仅可以在跨进程可以调用,也可以在进程内部调用。IBinder接口代表一种跨进程传输的能力,实现这个接口(不过通常都是去继承其子类android.os.Binder)就能将这个对象进行跨进程传递,IBinder用于定义了与远程对象进行交互的抽象协议。

1.1、boolean transact(int code, Parcel data, Parcel reply, int flags) send a call to an IBinder object

public boolean transact(int code, Parcel data, Parcel reply, int flags)

transact方法是Binder IPC机制中真正去执行跨进程的方法,通过把序列化后的对象封装为Parcel 数据进行传递。换言之,所有跨进程的方法的调用最终都是会经过transact。通过**transact方法可以向一个IBinder对象发送调用请求**,而在**Binder.onTransact方法接收到一个Binder对象的调用**。transact()方法是同步调用,通常调用发出后会阻塞直到对方的Binder.onTransact()方法调用完成后才会返回。

参数说明
code“协议”代码,取值为android.os.IBinder#FIRST_CALL_TRANSACTION+N,用AIDL时与定义接口方法的顺序有关
data传输给服务端的数据,如果你没有传输任何数据,你必须创建一个空的Parcel实例。
reply从服务端接收的数据,如果不需要处理返回的值,传入null
flagsIPC逻辑控制,如传入0表示是普通调用,而当且仅当调用者和响应者在不同进程时,传入android.os.IBinder#FLAG_ONEWAY时表示单向RPC,调用者会马上返回,而不必等结果从响应者响应之后再返回。

Parcel(一个通用缓冲区具体实现在Native层)除了有数据外还带有一些描述它内容的元数据(保存着IBinder对象的引用)。这样就能在缓冲区从一个进程移动到另一个进程时,保存这些引用。这确保了当一个 IBinder 在A进程内被写入到一个 Parcel 并发送到B进程后,B进程能将同一个 IBinder 的引用发送回A进程且确保A进程将收到相同的 IBinder 对象。因此可以将 IBinder/Binder 对象用作可以跨进程管理的唯一TOKEN。此外,系统为每一个进程维持一个Binder线程池,用于派发所有从其他进程发来的IPC调用。当进程A向进程B发起一个IPC 调用,A发出后,调用的线程就阻塞在transact()方法中了,进程B中Binder线程池的接收并调用Binder.onTransact(),完成后返回一个Parcel,然后A中的之前等待的线程在收到返回的Parcel才能继续执行,让你感觉像是在一个进程内线程之间的通信一样,实际上却是进程间的通信。

Binder机制还支持进程间的递归调用,transact()方法将在IBinder所在的进程不存在时抛出RemoteException异常

1.2、String getInterfaceDescriptor()

获取Binder 对应的标识,后续传入到queryLocalInterface中得到相应的IInterface对象。

1.3、boolean pingBinder() 检测Binder是否存活

如果目标进程不存在,那么调用pingBinder()时返回false,否则返回另一端的 pingBinder() 实现返回的结果(默认始终为 true)。

1.4、boolean isBinderAlive()检测托管进程是否存在

检查Binder所在的进程是否还活着,返回false则表示已经死亡,返回true有可能是正在返回结果或者活跃状态。

1.5、 IInterface queryLocalInterface(String descriptor) 获取Binder对应的本地实现对象

获取 Binder 对象的对应的本地实现对象, 返回null,则需要实例化一个代理类。

1.6、android.os.IBinder.DeathRecipient

监听当前进程所托管的Binder对象死亡的接口(只有一个方法android.os.IBinder.DeathRecipient#binderDied),可以通过linkToDeath(DeathRecipient recipient, int flags)方法注册监听IBinder生命周期,当Binder对象死亡时会被触发,而在不需要监听时调用unlinkToDeath(DeathRecipient recipient, int flags)。

1.7、android.os.IBinder 小结

总之,Binder 机制就是让我们感觉到跨进程的调用与进程内的调用没有什么区别。

  • IBindre是远程对象的基接口,不仅可以在跨进程可以调用,也可以在进程内部调用
  • 在远程调用的时候,一端用IBinder.transact()发送(封装为Parcel同步调用),另一端用Binder的Binder.onTransact()接受。
  • 系统为每个进程维护一个进行跨进程调用的Binder线程池。

2、android.os.Binder 和 android.os.BinderProxy

android.os.Binder 和android.os.BinderProxy实现了android.os.IBinder接口,因而都可以被跨进程传输,在跨越进程的时候,Binder驱动会自动完成这两个对象的转换。Binder 是IBinder的标准实现,IPC 执行时直接继承的基类,但只是一个basic IPC primitive,它对应用程序的生命周期没有影响且只有在创建它的进程继续运行时才有效,因此要正确使用它必须在android.app.Service、android.app.Activity 或 android.content. ContentProvider里让创建它的进程一致存活。

2.1、Binder 构造方法

只有一个构造方法,由Native 进行,会在Stub 自动被调用。Binder实现了IBinder接口,但是一般不需要直接实现此类,而是跟据你的需要由开发包中的工具根据AIDL语法自动生成Binder的派生类。

2.2、attachInterface(IInterface owner, String descriptor) 初始化

初始化Binder和对应的标识,在Stub 构造函数中被调用并传入Stub自身对象和对应的全类名。

public static abstract class Stub extends android.os.Binder implements com.xxx.netservice.ICallback{
private static final java.lang.String DESCRIPTOR = "com.xxx.netservice.ICallback";
/** Construct the stub at attach it to the interface. */
public Stub(){this.attachInterface(this, DESCRIPTOR);
}

2.3、boolean onTransact(int code, Parcel data, Parcel reply,

        int flags)

Binder中对应IBinder transact的实现,本质上就是调用Parcel 进行类“IO"操作。

2.4、android.os.BinderProxy

BinderProxy类也实现IBinder接口且是final类型的,主要API 的实现都是通过JNI调用Native 层的Binder,代表远程进程的Binder对象的本地代理,它的transact方法通过JNI去借助Binder驱动完成数据的传输,当完成数据传输后,会唤醒Server端,调用了Server端本地对象的onTransact函数,在Server进程里面,onTransact根据调用code会调用相关函数,接着将结果写入reply并通过super.onTransact返回给驱动,驱动唤醒挂起的Client进程里面的线程并将结果返回。

3、android.os.IInterface

Binder 的基类接口(定义的AIDL 实现时直接继承这个IInterface),主要是用于把IInterface 转为IBinder,以便确保代理对象可以返回正确的结果。

public interface IInterface{/*** Retrieve the Binder object associated with this interface.You must use this instead of a plain cast, so that proxy objects can return the correct result.*/public IBinder asBinder();
}

4、Stub和Stub.Proxy角色

Stub(抽象类)和Stub.Proxy(实体类) 是AIDL提供的标准实现定义的静态内部类,Stub.Proxy类和Stub类,都实现了AIDL接口,分别对应于本地进程和远程进程的Binder实例。其中Stub类在Server进程中实例化并通过 Service.onBind 方法传递给 Client 进程;而Client 进程接收到 IBinder 以后,通过 Stub.asInterface 方法转换成 AIDL接口之后使用Stub.asInterface 在本地进程工作时直接返回 Stub 实例,否则创建一个 Proxy 实例来代理通讯。

Stub#onTransact方法该方法运行在服务端中的Binder线程池中,服务端通过code确定客户端所请求的目标方法是什么,从data中取出目标方法所需的参数,然后执行目标方法,并将目标方法的返回值写入reply。如果该方法的返回false,则表示客户端的请求回失败,可以利用这个特性来做权限验证。

Stub.Proxy实现aidl接口并将方法的标识,参数和返回值对象传入方法mRemote.transact中,发起远程调用请求,同时挂起当前线程,然后服务端的Stub#onTransact被调用,当onTransact返回true,调用成功,从reply对象中取出返回值,返回给客户端调用方,当Client 进程使用时通过 Stub.asInterface 创建,同时会将方法调用的数据,都通过mRemote 转发给Server端的 Binder 实例。

package com.xx.netservice;public interface IBaseIPC extends android.os.IInterface {public static abstract class Stub extends android.os.Binder implements com.xx.netservice.IBaseIPC {private static final java.lang.String DESCRIPTOR = "com.xx.netservice.IBaseIPC";public Stub() {this.attachInterface(this, DESCRIPTOR);}/*** 无论是哪个进程,拿到反序列化的 IBinder 对象以后,通过这个静态方法来获取ICallback接口。* 如果是 Server 进程(local),可以从 binder 中直接取出之前 attach的IInterface 实例,那么调用ICallback的方法,就相当于直接调用Stub 实例的方法了。* 如果是 Client 进程,IBinder 只是系统在远程创建的一个 Proxy 类并无实现,因此iin 将变成 null,此时 asInterface 会创建一个Stub.Proxy 代理类,来实现 IBaseIPC 接口。*/public static com.xx.netservice.IBaseIPC asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.xx.netservice.IBaseIPC))) {return ((com.xx.netservice.IBaseIPC) iin);}return new com.xx.netservice.IBaseIPC.Stub.Proxy(obj);}@Overridepublic android.os.IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {java.lang.String descriptor = DESCRIPTOR;switch (code) {// Server 进程的 Binder,在这里接收 transaction,并将数据反序列化以后,调用 IBaseIPC 抽象方法。case TRANSACTION_baseIPC: {data.enforceInterface(descriptor);java.lang.String _arg0;_arg0 = data.readString();int _arg1;_arg1 = data.readInt();boolean _arg2;_arg2 = (0 != data.readInt());this.IBaseIPC(_arg0, _arg1, _arg2);reply.writeNoException();return true;}default: {return super.onTransact(code, data, reply, flags);}}}/*** Client 进程持有的代理类,通过 Stub.asInterface 创建,Proxy 也实现了 IBaseIPC,会将方法调用的数据,都通过 mRemote 转发给远程的 Binder 实体。*/private static class Proxy implements com.xx.netservice.IBaseIPC {private android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}@Overridepublic void baseIPC(java.lang.String type, int deviceType, boolean status) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeString(type);_data.writeInt(deviceType);_data.writeInt(((status) ? (1) : (0)));mRemote.transact(Stub.TRANSACTION_baseIPC, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}}static final int TRANSACTION_baseIPC = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);}public void baseIPC(java.lang.String type, int deviceType, boolean status) throws android.os.RemoteException;
}

未完待续…

相关文章:

Android 进阶——Framework核心 之Binder Java成员类详解(三)

文章大纲引言一、Binder Java家族核心成员关系图二、Binder Java家族核心成员源码概述1、android.os.IBinder1.1、boolean transact(int code, Parcel data, Parcel reply, int flags) send a call to an IBinder object1.2、String getInterfaceDescriptor()1.3、boolean ping…...

Maven

Maven 1.什么是Maven 官方网站 https://maven.apache.org/ Maven是一款服务于Java平台的自动化构建工具,它可以帮助我们更方便的对项目进行构建、管理项目jar包 ,包括: bulid 项目,切换 jar 版本,添加 jar, 删除 jar 包等 1.…...

1947抓住那头牛(队列 广度优先搜索)

目录 题目描述 解析 解题思路 代码部分 代码部分 运行结果 看看len数组中各个位置的标记值 为什么这样做一定是最短路径&#xff1a; 题目描述 农夫知道一头牛的位置&#xff0c;想要抓住它。农夫和牛都位于数轴上&#xff0c;农夫起始位于点N(0<N<100000)&…...

基于linux5.15.5的IMX 参考手册 ---21

基于linux5.15.5的IMX 参考手册 — 21 10.5.2高清多媒体接口&#xff08;HDMI&#xff09;和显示端口&#xff08;DP&#xff09;概述 10.5.2.1测试名称 •mxc_cec_test.out 10.5.2.1.1位置 /unit_tests/HDMI/ 10.5.2.1.2功能 验证HDMI CEC功能并向HDMI接收器发送断电命令。 1…...

Android Dalvik虚拟机 堆初始化流程

前言 上篇文章介绍了dalvik虚拟机启动流程&#xff0c;在dalvik虚拟机启动时调用了dvmGcStartup来启动堆。 本文介绍我们在日常开发使用Java时的堆创建流程。 Dalvik堆介绍 Dalvik虚拟机中&#xff0c;堆是由heap[0] Active堆和heap[1] Zygote堆两部分组成的。其中&#xff…...

0讲(补)——开发前必备基本常识

前言 专栏内容持续补充更新,目前正在进行优惠活动 目录 前言 一、函数的声明和定义 二、预编译 三、串口打印中的printf函数的使用...

JS学习笔记

1.WebAPIs简介导读Web APIs 和JS 基础关联性JS 基础阶段以及 Web APIs 阶段JS基础学习 ECMAScript 基础语法为后面作铺垫&#xff0c;Web APIs 是JS 的应用&#xff0c;大量使用JS基础语法做交互效果①JS 基础阶段我们学习的是ECMAScript 标准规定的基本语法要求同学们掌握JS 基…...

linux005之用户、组管理

linux用户管理简介&#xff1a; 任何使用linux系统的用户&#xff0c;都必须使用一个合法的账号和密码&#xff0c;账号和密码一般都是超级管理员创建&#xff0c;当然普通用户也可以创建用户&#xff0c;前提是必须拥有创建用户权限。 root是linux系统中默认创建的超级用户 创…...

列线图工具_Nomogram

定义 列线图是一种相对传统的分析方法&#xff0c;用于展示自变量和因变量的线性关系&#xff0c;及其特征的重要程度。 现在用SHAP&#xff0c;和机器学习库中的 Feature importance 工具可以实现类似甚至更好效果。不过很多传统的研究领域比较认这种方法。 列线图工具建立在…...

【C++】类和对象(一)

目录一、面向过程和面向对象初步认识二、类的引入三、类的定义四、类的访问限定符及封装4.1、访问限定符4.2、封装五、类的作用域六、类的实例化七、类对象的大小八、this指针8.1、this指针的引出8.2、this指针的特性8.3、C语言和C实现Stack的对比一、面向过程和面向对象初步认…...

Python获取搜索引擎结果

前言 想快速获取各个高校的博士招生网站&#xff0c;于是通过python先获取出有可能包含高校博士招生网站的URL&#xff0c;然后通过人为筛选得到了想要的招生网站&#xff08;注意&#xff0c;并非直接爬取&#xff0c;是间接获取的&#xff09;。 整理了一份网站名单&#x…...

2.4.8 PCIe——物理逻辑层——REFCLK

一、概述 pcie的参考时钟由板级输入&#xff0c;提供给IP内PHY层的PLL使用&#xff0c;由PLL产生core_clk和pipe_clk。 二、REFCLK产生方式 Serdes 所用时钟由 PHY 模块内的PLL生成&#xff0c;PLL的参考时钟可以由common clock&#xff08;外部背板提供&#xff09;、separ…...

树莓派4B arm64 搭建 docker+drone+gitea

树莓派4B arm64 搭建 dockerdronegitea 记录时间: 2023年02月10日 树莓派烧录 如何用树莓派搭建一台永久运行的个人服务器&#xff1f; https://mp.weixin.qq.com/s?__bizMzI5NjA0ODkwNA&mid2651847658&idx1&sn267a1257b43d4a76f2a081ed157b77f9&chksmf7b11…...

Java的JDBC编程

目录 1. 打开IDEA&#xff0c;新建Project 2. 引入依赖 &#xff08;1&#xff09;下载驱动包 &#xff08;2&#xff09;将驱动包导入Project 3. 编写代码 &#xff08;1&#xff09;创建数据源 &#xff08;2&#xff09;让代码和数据库服务器建立联系 &#xff08;3&…...

CSS:块格式化上下文(BFC)

块格式化上下文是块级盒子的布局过程发生的区域&#xff0c;也是浮动元素与其他元素交互的区域。 块格式化上下文(BFC)的创建 满足以下条件将创建块格式化上下文&#xff1a; 根元素&#xff08;&#xff09;浮动元素&#xff08;float 值不为 none&#xff09;绝对定位元素…...

paddle表情识别部署

表情识别模块1.环境部署1.1同样采用fastDeploy库1.2相关模型2.封装成静态库2.1参考[百度Paddle中PP-Mattingv2的部署并将之封装并调用一个C静态库](https://blog.csdn.net/weixin_43564060/article/details/128882099)2.2项目依赖添加2.3生成成功3.test3.1创建emotion_test项目…...

Python-第五天 Python函数

Python-第五天 Python函数一、函数介绍1. 什么事函数二、函数的定义1.函数的定义&#xff1a;2.案例三、函数的参数1.函数的传入参数2.案例升级四、函数的返回值1.什么是返回值2.返回值的语法3.None类型4.None类型的应用场景五、函数说明文档1.函数的说明文档2.在PyCharm中查看…...

【Python学习笔记】28.Python3 错误和异常

前言 作为 Python 初学者&#xff0c;在刚学习 Python 编程时&#xff0c;经常会看到一些报错信息&#xff0c;在前面我们没有提及&#xff0c;这章节我们会专门介绍。 Python3 错误和异常 Python 有两种错误很容易辨认&#xff1a;语法错误和异常。 Python assert&#xf…...

SQLServer 迁移到 MySQL 工具对比

我之所以会写这篇对比文章&#xff0c;是因为公司新产品研发真实经历过这个痛苦过程&#xff08;传统基于 SQL Server开发的C/S 产品转为 MySQL云产品&#xff09;。首次需要数据转换是测试环节&#xff0c;当时为了快速验证新研发云产品性能与结果准确性&#xff08;算法类&am…...

分析finebi5.x仪表板组件获取数据过程(数据是数据集或者sql的)

首先仪表板的公共连接类似:http://localhost:37799/webroot/decision/link/Bo6B 当我们访问这个连接时,会来到FineLinkAction的getShareReport方法。 public String getShareReport(HttpServletRequest req, HttpServletResponse res, @FinePathVariable("linkId"…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module

1、为什么要修改 CONNECT 报文&#xff1f; 多租户隔离&#xff1a;自动为接入设备追加租户前缀&#xff0c;后端按 ClientID 拆分队列。零代码鉴权&#xff1a;将入站用户名替换为 OAuth Access-Token&#xff0c;后端 Broker 统一校验。灰度发布&#xff1a;根据 IP/地理位写…...

多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验

一、多模态商品数据接口的技术架构 &#xff08;一&#xff09;多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如&#xff0c;当用户上传一张“蓝色连衣裙”的图片时&#xff0c;接口可自动提取图像中的颜色&#xff08;RGB值&…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用

中达瑞和自2005年成立以来&#xff0c;一直在光谱成像领域深度钻研和发展&#xff0c;始终致力于研发高性能、高可靠性的光谱成像相机&#xff0c;为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...

高分辨率图像合成归一化流扩展

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 1 摘要 我们提出了STARFlow&#xff0c;一种基于归一化流的可扩展生成模型&#xff0c;它在高分辨率图像合成方面取得了强大的性能。STARFlow的主要构建块是Transformer自回归流&#xff08;TARFlow&am…...