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

Android 系统Service流程

主要用到的源码文件
/frameworks/base/core/java/android/app/ContextImpl.java
和ams通信。
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
初始化Service,.管理服务 ActiveServices对象mServices
/frameworks/base/services/core/java/com/android/server/am/ActiveServices.java
ActiveServices.ServiceMap.mServicesByIntent  存储 基于service的intent 的FilterComparison和ServiceRecord信息。
ActiveServices.ServiceMap.mServicesByInstanceName 存储 基于service的ComponentName 和ServiceRecord信息。
ActiveServices.ServiceRestarter.mService 存储ServiceRecord对象,该对象是应用bindService时 基于当前service intent创建对ServiceRecord 类对象。

 /frameworks/base/core/java/android/app/LoadedApk.java
LoadedApk.ServiceDispatcher.mConnection 为应用绑定服务的ServiceConnection,
LoadedApk.ServiceDispatcher.mIServiceConnection 为 ServiceDispatcher.InnerConnection(继承IServiceConnection.Stub) 是aidl 服务端实现类对象。
  一个context只会创建一次InnerConnection对象。该对象在绑定服务时候会存储在ConnectionRecord.conn,ServiceRecord.connections 的key中。
 /frameworks/base/services/core/java/com/android/server/am/ServiceRecord.java
 用来描述一个 Service,因为继承 Binder 可以通过aidl 跨进程传递参数。
 其中 ServiceRecord.bindings ArrayMap存储Intent和IntentBindRecord.
 ServiceRecord.connections 存储 IServiceConnection aidl 服务端实现类InnerConnection对象binder 和ConnectionRecord对象.
 /frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
 描述一个进程
 /frameworks/base/services/core/java/com/android/server/am/ConnectionRecord.java
 描述应用程序进程和 Service建立的一次通信,即客户端调用一次bindService会创建一个ConnectionRecord对象。
ConnectionRecord.binding 存储AppBindRecord对象。
ConnectionRecord.conn 存储 IServiceConnection aidl 服务端实现类InnerConnection对象。
 /frameworks/base/services/core/java/com/android/server/am/AppBindRecord.java
  应用程序进程通过Intent绑定Service时用来描述被绑定的Service,通过AppBindRecord来维护Service与应用程序进程之间的关联。
AppBindRecord.connections 存储ArraySet<ConnectionRecord> 数组。描述所有绑定通信记录的信息
AppBindRecord.intent     存储IntentBindRecord对象。
AppBindRecord.service    存储ServiceRecord对象。
AppBindRecord.client    存储ProcessRecord对象。描述谁绑定的Service

/frameworks/base/services/core/java/com/android/server/am/IntentBindRecord.java
 用于描述绑定Service的Intent
注:不同的应用进程也可能会创建相同的Intent来绑定同一个Serivce。比如说一些公共的、常用的Service。

一、Service初始化

从 《AMS初始化、应用启动及activity启动流程分析(Android11)》 一文中ams 初始化流程可知。
SystemServer进程启动时SystemServer.startBootstrapServices会:
1.创建ActivityTaskManagerService并启动
2.创建ActivityManagerService并启动
 调用 ActivityManagerService.Lifecycle.startService(mSystemServiceManager, atm)
ActivityManagerService.Lifecycle.startService(SystemServiceManager ssm, ActivityTaskManagerService atm) 调用ssm.startService(ActivityManagerService.Lifecycle.class).getService()
ssm为SystemServiceManager即用
SystemServiceManager.startService(Class<T> serviceClass) 。
会创建ActivityManagerService.Lifecycle对象,通过 constructor.newInstance(mContext)。
ActivityManagerService.Lifecycle.Lifecycle 调用mService = new ActivityManagerService(context, sAtm)。
ActivityManagerService.ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) 构造方法。
会调用 mServices = new ActiveServices(this) 创建 ActiveServices对象mServices用来管理服务。
ActiveServices.ActiveServices(ActivityManagerService service) 调用 mAm = service 将ActivityManagerService 赋值给变量mAm。

二、启动服务 startService

Service客户端进程:
Context.startService(serviceIntent)  Context是抽象类,由其子类ContextImpl实现
ContextImpl.startService(Intent service) 调用startServiceCommon(service, false, mUser)
ContextImpl.startServiceCommon(Intent service, ..) 调用 ActivityManager.getService().startService(mMainThread.getApplicationThread(), service,...) 
通过aidl调用ams方法

system_server进程:
ActivityManagerService.startService(IApplicationThread caller, Intent service,...) 调用 mServices.startServiceLocked(caller, service,...)
ActiveServices.startServiceLocked(IApplicationThread caller, Intent service...) 调用startServiceLocked(caller, service,..false)
ActiveServices.startServiceLocked(IApplicationThread caller, Intent service...boolean allowBackgroundActivityStarts) 主要执行
1.  基于service对应的ServiceRecord获取ServiceLookupResult
调用res =retrieveServiceLocked(service, null, resolvedType, callingPackage,callingPid, callingUid, userId, true, callerFg, false, false)
ActiveServices.retrieveServiceLocked(Intent service,...)  基于service Intent获取或创建ServiceRecord对象后封装到ServiceLookupResult类中返回。
如果service已经启动了,从ServiceMap.mServicesByInstanceName 取出service 并返回。
如果当前service未启动, ServiceMap.mServicesByInstanceName 中当前service为空。
则基于当前service intent 调用r = new ServiceRecord(...) 创建 ServiceRecord r,  并封装到ServiceLookupResult返回。
且将相关信息保存到ServiceMap中变量 mServicesByIntent和mServicesByInstanceName中。
2. 从ServiceLookupResult取出ServiceRecord r,  调用startServiceInnerLocked(smap, service, r, callerFg, addToStarting)
ActiveServices.startServiceInnerLocked(...) 调用bringUpServiceLocked(r, service.getFlags(), callerFg, false, false)
ActiveServices.bringUpServiceLocked(ServiceRecord r...) 执行如下2步 来启动服务。
先调用 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false) 获取service所在进程。
2.1 如果进程存在,调用 realStartServiceLocked(r, app, execInFg) 启动服务
2.2 如果进程不存在调用app=mAm.startProcessLocked(procName, r.appInfo,...)  创建并启动进程。进程创建好再启动服务。
同时调用mPendingServices.add(r) 将ServiceRecord添加到待启动服务列表mPendingServices中,
ActivityManagerService.startProcessLocked(...) 从《AMS初始化、应用启动及activity启动流程分析(Android11)》一文可知,启动进程最终会调用
ActivityManagerService.attachApplicationLocked(IApplicationThread thread,int pid, int callingUid, long startSeq) 该方法会调用mServices.attachApplicationLocked(app, processName)
ActiveServices.attachApplicationLocked(ProcessRecord proc, String processName) 遍历 mPendingServices
调用 sr = mPendingServices.get(i) 获取ServiceRecord后调用 realStartServiceLocked(sr, proc, sr.createdFromFg)启动服务
即2.1 2.2都会调用
ActiveServices.realStartServiceLocked(ServiceRecord r,ProcessRecord app, boolean execInFg) 执行2步
调用 app.thread.scheduleCreateService(r, r.serviceInfo,..)
ActivityThread. scheduleCreateService(IBinder token,ServiceInfo info..) 调用sendMessage(H.CREATE_SERVICE, s) 切换到主线程
ActivityThread.H.handleMessage(Message msg)  case CREATE_SERVICE: 调用handleCreateService((CreateServiceData)msg.obj)
ActivityThread.handleCreateService(CreateServiceData data) 
#1先创建service对应的Application对象,通过调用app = packageInfo.makeApplication(false, mInstrumentation) 这里mInstrumentation为空即无需调用Application.onCreate()方法.
#2 基于service信息创建Service对象,调用 service = packageInfo.getAppFactory().instantiateService(cl, data.info.name, data.intent)
#3 初始化service 调用service.attach(context, this, data.info.name, data.token, app,ActivityManager.getService())
#4 调用service的onCreate方法,调用 service.onCreate(),同时调用mServices.put(data.token, service) 将ServiceRecord 对应的IBinder 和当前启动的service对象放到mServices列表中。

三、绑定服务 bindService

Service客户端进程:
Context.bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE) Context是抽象类,由其子类ContextImpl实现
ContextImpl.bindService(Intent service, ServiceConnection conn, int flags) 调用bindServiceCommon(service, conn, flags, null, mMainThread.getHandler(), null,getUser()) 这里instanceName为空
ContextImpl.bindServiceCommon(Intent service, ServiceConnection conn,...) 调用ActivityManager.getService().bindIsolatedService(mMainThread.getApplicationThread(),getActivityToken(), service,.sd,..)
这里的sd为 IServiceConnection aidl 服务端实现类 InnerConnection 对象mIServiceConnection。
具体是通过调用 sd = mPackageInfo.getServiceDispatcher(conn, getOuterContext(), handler, flags)
LoadedApk.getServiceDispatcher(ServiceConnection c,...) 调用getServiceDispatcherCommon(c, context, null, executor, flags)
LoadedApk.getServiceDispatcherCommon(ServiceConnection c,...) 调用map = mServices.get(context) 基于当前的context获取 aidl 服务端实现类InnerConnection对象mIServiceConnection,
    如果存在返回该mIServiceConnection对象。
    如果不存在,调用 sd = new ServiceDispatcher(c, context, handler, flags) 创建ServiceDispatcher对象,
    ServiceDispatcher.ServiceDispatcher(ServiceConnection conn,...)  构造方法调用mIServiceConnection = new InnerConnection(this) 创建InnerConnection(继承IServiceConnection.Stub) 为IServiceConnection aidl 服务端实现类。
    getServiceDispatcherCommon最终返回IServiceConnection aidl 服务端实现类InnerConnection对象mIServiceConnection。
即bindServiceCommon方法中sd为IServiceConnection aidl 服务端实现类InnerConnection对象mIServiceConnection。且一个context只会创建一次InnerConnection对象。
这里如果Context 是app Context则 getActivityToken为null,
bindServiceCommon方法通过aidl调用ams方法

system_server进程:
ActivityManagerService.bindIsolatedService(IApplicationThread caller, IBinder token, Intent service,. Intent service.IServiceConnection connection..)  调用mServices.bindServiceLocked(caller, token, service,...) 
ActiveServices.bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,. final IServiceConnection connection,...) 主要执行如下几步
1.获取或创建service后,获取封装service的ServiceLookupResult对象 res。 调用res = retrieveServiceLocked(service,..)
    ActiveServices.retrieveServiceLocked(Intent service,...)  流程同二.1 
2. 先从 bindings 映射表中查找或新建 AppBindRecord, 通过调用AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp) 。
    retrieveAppBindingLocked方法中 先调用filter = new Intent.FilterComparison(intent) 基于Intent创建filter,然后调用 IntentBindRecord i = bindings.get(filter) 从bindings列表获取IntentBindRecord。
    如果bindings列表获取IntentBindRecord为空, 调用i = new IntentBindRecord(this, filter)创建 IntentBindRecord对象,且调用bindings.put(filter, i) 将IntentBindRecord对象添加到ServiceRecord.bindings 列表。
    最后调用a = new AppBindRecord(this, i, app) 创建AppBindRecord 并返回。
    即将封装了service的Intent的Intent.FilterComparison对象赋值给IntentBindRecord.intent.而AppBindRecord.intent为该IntentBindRecord对象。
然后调用ConnectionRecord c = new ConnectionRecord(b, activity,connection, ......)。
建立 binder 和 ConnectionRecord 列表及AppBindRecord的映射关系。具体流程是:
#1 调用 binder = connection.asBinder(),获取IServiceConnection aidl 服务端实现类InnerConnection对象binder 。
#2 s.addConnection(binder, c) ,将IServiceConnection aidl 服务端实现类InnerConnection对象binder 和ConnectionRecord对象存储到ServiceRecord.connections.
#3 b.connections.add(c)  将ConnectionRecord对象 添加到 AppBindRecord.connections列表中。因为不同的应用进程也可能会创建相同的Intent来绑定同一个Serivce,所以connections是列表。
3.如果flags == BIND_AUTO_CREATE 调用 bringUpServiceLocked(s, service.getFlags(), callerFg, false,permissionsReviewRequired) != null)
ActiveServices.bringUpServiceLocked(ServiceRecord r...)  同二.2  会创建进程(若进程不存在)并 启动服务。
4.如果service未绑定过(!b.intent.requested) 调用 requestServiceBindingLocked(s, b.intent, callerFg, false)
ActiveServices.requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i...) 调用r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,r.app.getReportedProcState())
这里的r为ServiceRecord(继承Binder),然后调用i.requested = true
ActivityThread.ApplicationThread.scheduleBindService(IBinder token, Intent intent,boolean rebind, int processState) 
调用sendMessage(H.BIND_SERVICE, s) 这里s = new BindServiceData(),s.token = token ,s.intent = intent, token为启动服务创建的ServiceRecord对象
ActivityThread.H.handleMessage case BIND_SERVICE: 调用handleBindService((BindServiceData)msg.obj)
ActivityThread.handleBindService(BindServiceData data) 方法中
#1 调用Service s = mServices.get(data.token) 基于ServiceRecord获取Service类对象。
#2 调用 binder = s.onBind(data.intent) 这里binder为 调用Service.onBind(Intent intent) 返回的调用Service的aidl服务实现类的binder 例如:xxService = new xxService.Stub
#3 调用ActivityManager.getService().publishService(data.token, data.intent, binder),其中binder = s.onBind(data.intent)
通过aidl跨进程调用ams方法

system_server进程:
ActivityManagerService.publishService(IBinder token, Intent intent, IBinder service) 调用mServices.publishServiceLocked((ServiceRecord)token, intent, service)
ActiveServices.publishServiceLocked(ServiceRecord r, Intent intent, IBinder service)  主要调用
#1.调用Intent.FilterComparison filter = new Intent.FilterComparison(intent) 基于Intent创建 Intent.FilterComparison对象filter。
#2.调用 IntentBindRecord b = r.bindings.get(filter) 基于Intent对应的 Intent.FilterComparison 从ServiceRecord中获取IntentBindRecord对象。
#3.调用b.binder = service 将Service的aidl服务实现类 对象赋值给binder。即将服务发布绑定到 ServiceRecord.bindings中IntentBindRecord.binder中。
调用 b.requested = true  设置service已绑定。b.received = true 设置
#4.从ServiceRecord.connections列表ArrayMap遍历其中的ConnectionRecord c,调用c.conn.connected(r.name, service, false) 调用同下5
5.如果service已经启动且绑定过 (s.app != null && b.intent.received),调用c.conn.connected(s.name, b.intent.binder, false),其中c为ConnectionRecord对象。c.conn为缓存的 IServiceConnection aidl 服务端实现类InnerConnection对象。
 b.intent 为 AppBindRecord.intent,即IntentBindRecord 为封装了service的Intent的Intent.FilterComparison对象的IntentBindRecord对象.
即通过aidl 跨进程调用 IServiceConnection aidl 服务端实现类InnerConnection.connected方法

Service客户端进程:
LoadedApk.ServiceDispatcher.InnerConnection.connected(ComponentName name, IBinder service, boolean dead) 调用sd.connected(name, service, dead),
其中sd为应用调用bindService时创建的ServiceDispatcher对象,
LoadedApk.ServiceDispatcher.connected(ComponentName name, IBinder service, boolean dead) 调用doConnected(name, service, dead),
LoadedApk.ServiceDispatcher.doConnected(ComponentName name, IBinder service, boolean dead) 该方法先掉info = new ConnectionInfo()创建 LoadedApk.ServiceDispatcher.ConnectionInfo对象
然后调用info.binder = service  将Service的aidl服务实现类 对象赋值给binder。
调用 mConnection.onServiceConnected(name, service) 调用客户端的ServiceConnection.onServiceConnected方法
ServiceConnection.onServiceConnected(ComponentName name, IBinder service)  service为 客户端获取到Service的aidl服务实现类的binder,即可以通过该binder同service服务端进行aidl 跨进程通信。

四、总结:

1.应用bindService时 会先创建一个LoadedApk.ServiceDispatcher对象和一个LoadedApk.ServiceDispatcher.InnerConnection(继承IServiceConnection.Stub) 是aidl 服务端实现类对象mIServiceConnection,
2.mIServiceConnection会被存储到ams中ActiveServices.ServiceRestarter.mService(ServiceRecord对象).connections 。
3.然后ams通过调用LoadedApk中 aidl 服务端实现类对象mIServiceConnection.connected(r.name, service, false)  方法调用到 Service客户端进程,参数service 为Service的aidl服务实现类的binder。
最终调用Service客户端应用的ServiceConnection.onServiceConnected方法,Service客户端应用拿到service binder后可以和service aidl通信。
 

相关文章:

Android 系统Service流程

主要用到的源码文件 /frameworks/base/core/java/android/app/ContextImpl.java 和ams通信。 /frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java 初始化Service,.管理服务 ActiveServices对象mServices /frameworks/base/services/core/…...

Gartner预测2025年网络安全正在进入AI动荡时期:软件供应链和基础设施技术堆栈中毒将占针对企业使用的人工智能恶意攻击的 70% 以上

Gartner 预测&#xff0c;网络安全正在进入 AI 动荡时期。安全和风险管理领导者必须根据早期生成式 AI 部署的失败以及 AI 代理清洗来评估即将到来的 AI 进展。 主要发现 随着各大企业开展大量人工智能采用和开发项目&#xff0c;应用安全弱点的暴露程度不断提高&#xff0c;包…...

华为最新OD机试真题-最长子字符串的长度(一)-Python-OD统一考试(E卷)

最新华为OD机试考点合集:华为OD机试2024年真题题库(E卷+D卷+C卷)_华为od机试题库-CSDN博客 每一题都含有详细的解题思路和代码注释,精编c++、JAVA、Python三种语言解法。帮助每一位考生轻松、高效刷题。订阅后永久可看,发现新题及时跟新。 题目描述: 给你一个字符串…...

HAL库框架学习总结

概述&#xff1a;HAL库为各种外设基本都配了三套 API&#xff0c;查询&#xff0c;中断和 DMA。 一、HAL库为外设初始化提供了一套框架&#xff0c;这里以串口为例进行说明&#xff0c;调用函数 HAL_UART_Init初始化串口&#xff0c;此函数就会调用 HAL_UART_MspInit&#xff0…...

基于Spring Integration的ESB与Kettle结合实现实时数据处理技术

一、方案概述 在当今数字化时代,企业面临着海量数据的实时处理与传输挑战。ESB(企业服务总线)作为系统集成的核心组件,承担着不同协议数据的接入与转换任务,而Kettle作为一款功能强大的ETL(Extract, Transform, Load)工具,在数据抽取、转换与加载方面表现出色。将ESB与…...

qt QOpenGLContext详解

1. 概述 QOpenGLContext 是 Qt 提供的一个类&#xff0c;用于管理 OpenGL 上下文。它封装了 OpenGL 上下文的创建、配置和管理功能&#xff0c;使得开发者可以在 Qt 应用程序中以平台无关的方式使用 OpenGL。通过 QOpenGLContext&#xff0c;可以轻松地创建和管理 OpenGL 上下…...

探索顶级汽车软件解决方案:驱动行业变革的关键力量

在本文中&#xff0c;将一同探索当今塑造汽车行业的最具影响力的软件解决方案。从设计到制造&#xff0c;软件正彻底改变车辆的制造与维护方式。让我们深入了解这个充满活力领域中的关键技术。 设计软件&#xff1a;创新车型的孕育摇篮 车辆设计软件对于创造创新型汽车模型至…...

Deepseek R1模型本地化部署+API接口调用详细教程:释放AI生产力

文章目录 前言一、deepseek R1模型与chatGPT o1系列模型对比二、本地部署步骤1.安装ollama2部署DeepSeek R1模型删除已存在模型&#xff0c;以7b模型为例 三、DeepSeek API接口调用Cline配置 前言 随着最近人工智能 DeepSeek 的爆火&#xff0c;越来越多的技术大佬们开始关注如…...

DeepSeek 概述与本地化部署【详细流程】

目录 一、引言 1.1 背景介绍 1.2 本地化部署的优势 二、deepseek概述 2.1 功能特点 2.2 核心优势 三、本地部署流程 3.1 版本选择 3.2 部署过程 3.2.1 下载Ollama 3.2.2 安装Ollama 3.2.3 选择 r1 模型 3.2.4 选择版本 3.2.5 本地运行deepseek模型 3.3.6 查看…...

FFmpeg Video options

FFmpeg视频相关选项 1. -vframes number (output) 设置输出视频帧数 示例&#xff1a; ffmpeg -i input.mp4 -vframes 90 output.mp4 表示输出90帧视频 2. -r[:stream_specifier] fps (input/output,per-stream) 设置帧率(rate) 示例&#xff1a; ffmpeg -i input.mp4…...

从51到STM32:PWM平滑迁移方案

引言 对于习惯使用51单片机的开发者而言&#xff0c;转向STM32时可能会面临开发环境和硬件差异的挑战。本文以PWM&#xff08;脉宽调制&#xff09;功能为例&#xff0c;分享从51到STM32的平滑迁移方案&#xff0c;帮助开发者快速适应STM32的开发模式。 一、PWM实现原理对比 …...

openCV中如何实现滤波

图像滤波用于去除噪声和图像平滑&#xff0c;OpenCV 提供了多种滤波器&#xff1a; 1.1. 均值滤波&#xff1a; import cv2# 读取图像 image cv2.imread("example.jpg")# 均值滤波 blurred_image cv2.blur(image, (5, 5)) # (5, 5) 是滤波核的大小 滤波核大小的…...

BGP配置华为——路由汇总

实验拓扑 实验要求 1.R1,R2,R3间运行BGP&#xff0c;搭建EBGP邻居 2.R3一段的网络实现自动聚合&#xff0c;R1一端的网络实现手动路由聚合 3.启用as-set防环 实验配置 配置相关IP 过程省略&#xff0c;结果如图 R1 R2 R3 配置EBGP [R1]bgp 100 [R1-bgp]router 10.10.1…...

机器学习核心算法解析

机器学习核心算法解析 机器学习是人工智能的核心技术之一&#xff0c;它通过从数据中学习模式并做出预测或决策。本文将深入解析机器学习的核心算法&#xff0c;包括监督学习、无监督学习和强化学习&#xff0c;并通过具体案例和代码示例帮助读者理解这些算法的实际应用。 1. …...

【C++学习篇】C++11

目录 ​编辑 1. 初始化列表{} 1.1 C98中的{} 1.2 C11中的{} 2. C11中的std::initializer_list 3. 右值引用和移动语义 3.1 左值和右值 3.2 左值引用和右值引用 3.3 引用延长生命周期 3.4 左值和右值的参数匹配 3.5 右值引⽤和移动语义的使⽤场景 3.5.1 左值引⽤…...

SQLite 数据库:优点、语法与快速入门指南

文章目录 一、引言二、SQLite 的优点 &#x1f4af;三、SQLite 的基本语法3.1 创建数据库3.2 创建表3.3 插入数据3.4 查询数据3.5 更新数据3.6 删除数据3.7 删除表 四、快速入门指南4.1 安装 SQLite4.2 创建数据库4.3 创建表4.4 插入数据4.5 查询数据4.6 更新数据4.7 删除数据4…...

数据结构——二叉树(2025.2.12)

目录 一、树 1.定义 &#xff08;1&#xff09;树的构成 &#xff08;2&#xff09;度 2.二叉树 &#xff08;1&#xff09;定义 &#xff08;2&#xff09;二叉树的遍历 &#xff08;3&#xff09;遍历特性 二、练习 1.二叉树 &#xff08;1&#xff09;创建二叉树…...

图神经网络简介

一、说明 本文介绍了GNN网络一些要素&#xff0c;其中与CNN进行过一些对比&#xff0c;并且对GNN的一些统计原理进行介绍。 二、介绍 对于不同类型的训练数据集&#xff0c;卷积神经网络 &#xff08;CNN&#xff09; 擅长处理方形或网格状或欧几里得结构化数据&#xff0c;…...

小程序报错The JavaScript function Pointer_stringify(ptrToSomeCString)

小程序报错The JavaScript function Pointer _stringify&#xff08;ptrToSomeCString&#xff09; 介绍修改地址总结 介绍 这个报错是我在打包小程序在手机上运行时报的错&#xff0c;这个地方问题是个小问题&#xff0c;其实就是Pointer_stringify(ptrToSomeCString) 函数过时…...

DeepSeek 与网络安全:AI 驱动的智能防御

&#x1f4dd;个人主页&#x1f339;&#xff1a;一ge科研小菜鸡-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 1. 引言 随着人工智能&#xff08;AI&#xff09;的快速发展&#xff0c;深度学习技术正渗透到多个领域&#xff0c;从医疗诊断到…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

《Playwright:微软的自动化测试工具详解》

Playwright 简介:声明内容来自网络&#xff0c;将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具&#xff0c;支持 Chrome、Firefox、Safari 等主流浏览器&#xff0c;提供多语言 API&#xff08;Python、JavaScript、Java、.NET&#xff09;。它的特点包括&a…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)

目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关&#xff0…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】&#xff0c;分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...