news 2026/9/3 7:49:22

STM32宠物智能项圈:高精度定位+抗干扰计步+SOC精准估算

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
STM32宠物智能项圈:高精度定位+抗干扰计步+SOC精准估算

简介:本资源是一套完整的基于STM32的宠物智能项圈嵌入式开发源码工程,面向嵌入式初学者、物联网项目开发者及智能硬件爱好者,解决宠物定位追踪、日常活动监测(计步)、低功耗充电状态可视化等核心功能的软硬件协同实现问题。压缩包共629个文件,涵盖341个C源文件(含HAL驱动、传感器采集、GPS解析、低功耗管理等模块)、112个头文件(定义接口与配置参数)、43个汇编启动文件及28个IAR工程配置文件(.icf),另有编译输出文件(.axf、.map、.o)和CMSIS-DSP数学库支持文件,整体大小为19.72MB。目前已有814人学习下载。读者可直接导入Keil或IAR环境编译运行,获得包含GPS定位数据解析、三轴加速度计计步算法、锂电池电量检测与LCD/LED充电状态显示的完整可执行方案,并参考大量HAL底层驱动代码与硬件抽象层设计逻辑,快速掌握STM32F1系列在低功耗IoT设备中的典型应用架构。

1. 项目概述:一个真正能落地的宠物智能项圈,不是玩具,是责任

我做过三轮宠物健康监测设备的原型开发,从最早用Arduino+GPS模块搭出能跑通的demo,到后来用ESP32做低功耗版本,再到这次彻底沉下心来用STM32F103C8T6重做整套系统——不是为了炫技,而是因为真实养猫三年、遛狗五年后,我彻底认清一件事:市面上90%的宠物项圈,要么是手机App里跳动的假数据,要么是充一次电撑不过48小时的“电子手镯”。而这个标题里写的“基于STM32宠物智能项圈源码资料(定位+计步+充电显示)”,恰恰踩中了三个最硬核也最容易被忽略的痛点:定位不是“有就行”,而是“准不准、快不快、省不省”;计步不是“数个数”,而是“判得清抬腿还是抖毛”;充电显示不是“亮个灯”,而是“告诉你电池还剩多少mAh,而不是‘还有两格电’这种玄学”。这套源码,是我把实验室里调试了17版的固件、PCB打样5次的硬件设计、以及在小区里跟23只猫狗实测跑出来的数据模型,全部打包整理出来的结果。它不依赖云服务、不强制联网、不绑定任何App,所有逻辑都在MCU本地完成;它用的是标准UART+I2C接口,OLED屏驱动、MAX7219数码管、ATK-NEO-6M GPS模块、MPU6050姿态传感器、TP4056充电管理芯片,全是淘宝上15元以内能买到的现货;它支持离线轨迹回放、跌倒检测阈值可调、充电状态精确到±3%误差。如果你正在做一个真实的宠物产品,或者想带学生做一个有工程闭环的毕业设计,又或者只是想搞懂“为什么我的STM32计步老是多算200步”,那这套资料不是锦上添花,而是绕不开的起点。

2. 整体架构设计与技术选型逻辑:为什么非得是STM32F103,而不是ESP32或树莓派

2.1 主控芯片选择:F103C8T6不是“将就”,而是“刚刚好”

很多人看到“STM32”第一反应是“太老了吧?现在都用H7了”。但做宠物项圈,恰恰需要F103这种“老而弥坚”的芯片。我们来算一笔账:一只成年金毛犬项圈,内部空间极限是35mm×25mm×12mm,电池容量最大只能塞进500mAh锂聚合物电池。如果用ESP32-WROOM-32,Wi-Fi/BLE双模射频功耗在接收状态下就达80mA,待机电流也有20μA——这还没算上GPS冷启动时的250mA峰值电流。而F103C8T6在Stop模式下电流仅2.5μA,配合RTC唤醒,实测待机功耗压到8μA以下。更关键的是外设匹配度:它自带3个通用定时器(TIM2/TIM3/TIM4),正好分别用于GPS秒脉冲同步、MPU6050姿态采样中断、OLED刷新;2路SPI(SPI1接OLED,SPI2接SD卡存轨迹);1路I2C(接MPU6050和BQ24075充电管理芯片);2路USART(USART1接GPS模块,USART2接调试串口)。这些外设不用软件模拟,硬件级稳定。我试过用STM32F407移植同一套代码,虽然性能富余,但功耗反而高15%,因为F4的Flash预取和缓存机制在小任务场景下反而成了累赘。所以F103不是落后,是在物理约束下的最优解。

2.2 定位模块选型:NEO-6M不是“便宜”,而是“可靠”

标题里没写具体型号,但源码里默认适配的是ATK-NEO-6M(UBLOX NEO-6M芯片)。有人会问:“为什么不选M8N或M9N?”答案很实在:M8N在开阔地确实快1秒,但在城市峡谷里,它频繁切换卫星导致定位漂移更大;M9N支持多频段,但成本翻倍且功耗高30%。NEO-6M的固件是UBLOX官方认证的,支持NMEA-0183协议,输出GPGGA/GPRMC等标准语句,解析起来零学习成本。更重要的是它的“热启动时间”——在项圈摘下再戴上时,如果上次关机前保存了星历数据(almanac),热启动只要1.2秒;而M8N在同样条件下要2.8秒。对宠物来说,这1.6秒意味着它刚跑出小区门就被记录到轨迹起点,而不是在门口兜了三圈才开始画线。源码里专门做了星历缓存机制:每次定位成功后,把当前UTC时间、卫星ID、伪距残差存到EEPROM里,下次开机优先加载。实测连续7天未充电,热启动成功率仍保持98.7%。

2.3 计步算法核心:不是加速度积分,而是状态机判别

所有新手都以为计步就是“检测加速度峰值”。但猫甩尾巴、狗抖毛、项圈被树枝刮擦,都会产生类似走路的加速度波形。这套源码用的是三级状态机:
第一级是动态阈值滤波:每200ms采集MPU6050的三轴加速度,计算矢量和(√(ax²+ay²+az²)),然后用滑动窗口(长度16)求均值,再动态设定阈值为均值×1.8。这样当宠物静止时阈值自动降低,活动时阈值自动抬高;
第二级是相位识别:走路时前后肢交替,加速度波形呈现“峰-谷-峰”周期,而抖毛是单峰高频震荡。源码用了一个极简的相位差检测:记录连续两个峰值之间的时间差,若在300ms~1200ms区间内,则标记为有效步态周期;
第三级是姿态校验:MPU6050同时输出俯仰角(Pitch)和横滚角(Roll)。正常行走时,Pitch角变化幅度在±15°内,Roll角变化小于±5°;如果Pitch突变超过30°(比如摔倒),则该周期步数清零并触发跌倒告警。
这套逻辑在23只不同体型宠物(从2kg的吉娃娃到45kg的拉布拉多)实测中,误检率<2.3%,漏检率<1.7%,远超某宝99元项圈的15%误检率。

2.4 充电显示设计:不是“亮灯”,而是“读电压+查温度+算SOC”

标题里“充电显示”四个字看似简单,但多数开源项目只做到“USB插上就亮绿灯”。而真实场景是:夏天车里暴晒后项圈温度达58℃,此时即使电池电压3.8V,也不能按常温SOC估算;冬天零下10℃,锂电池内阻飙升,3.6V可能只剩30%电量。源码里用了三重校准:

  • 电压查表法:预先在恒温箱里测了-10℃/0℃/25℃/40℃/50℃五个温度点下,3.0V~4.2V每0.05V对应的SOC值,生成5张17×1表格;
  • 温度补偿:用DS18B20测电池表面温度,插值选取对应温度表;
  • 库仑积分修正:TP4056充电芯片的CHRG引脚输出充电电流脉冲,源码用TIM3的输入捕获功能统计单位时间脉冲数,换算成实时充电电流(精度±5mA),对SOC做微分修正。
    最终OLED上显示的不是“⚡⚡⚡”,而是“剩余电量:63%(382mAh)|当前温度:32℃|预计充满:28分钟”。这才是工程师该给宠物主看的数据。

3. 核心模块实现细节与实操要点:每一行代码都有它的战场

3.1 GPS定位模块:从原始NMEA到可用经纬度的完整链路

GPS模块通过USART1以9600bps速率发送NMEA语句,但直接解析GPGGA会有三个坑:
第一坑是校验和错误:NMEA语句末尾的“XX”是异或校验,但NEO-6M在信号弱时偶尔发错校验位。源码没用“跳过校验”的懒办法,而是做了容错解析:先按逗号分割字段,再对$后到前的所有字符做异或,若不匹配,则检查相邻两句是否内容一致(GPS每秒发一句,弱信号时可能重复),取两次一致的为准。
第二坑是UTC时间漂移:GPRMC里的UTC时间来自卫星原子钟,但MCU的RTC晶振有±20ppm误差。源码在每次成功解析GPRMC后,用GPS时间校准RTC:计算GPS UTC秒数与RTC秒数的差值Δt,然后用Δt×0.98作为本次校准量(留2%余量防突变),避免RTC日积月累跑偏。
第三坑是坐标精度陷阱:GPGGA里纬度/经度是“ddmm.mmmm”格式,比如“3112.3456”代表31°12.3456′,但直接转成十进制度会丢精度。源码用定点数运算:先分离度分(3112→31°12′),再把小数部分×10000转成整数毫分,最后统一换算为“度×1000000”存储,避免浮点运算引入的舍入误差。实测在100米范围内,坐标重复精度达0.8米,足够区分“在小区东门”和“在东门对面奶茶店”。

3.2 计步算法代码层实现:状态机如何用寄存器级操作落地

MPU6050通过I2C以100kHz速率传输数据,但源码没用HAL库的HAL_I2C_Master_Transmit(),而是直接操作FSMC和GPIO寄存器——因为HAL库每次调用会消耗约12μs开销,而计步需要每200ms采样一次,累积开销会让定时器精度失守。核心代码片段如下:

// 初始化I2C:直接配置CR1/CR2/OAR1/TRISE寄存器,关闭ACK使能(只读MPU6050的ACCEL_XOUT_H) I2C1->CR1 &= ~I2C_CR1_ACK; I2C1->CR2 = 0x00000010; // 配置时钟频率为100kHz // 读取加速度:发送设备地址+寄存器地址,然后连续读6字节 I2C1->DR = 0xD0; // MPU6050写地址 while(!(I2C1->SR1 & I2C_SR1_SB)); // 等待起始位 I2C1->DR = 0x3B; // ACCEL_XOUT_H寄存器地址 while(!(I2C1->SR1 & I2C_SR1_ADDR)); // 等待地址响应 I2C1->SR1; I2C1->SR2; // 清除ADDR标志 // 连续读取:设置ACK=1,读6字节 for(uint8_t i=0; i<6; i++) { if(i==5) I2C1->CR1 &= ~I2C_CR1_ACK; // 最后一字节不ACK while(!(I2C1->SR1 & I2C_SR1_RXNE)); // 等待接收完成 raw_data[i] = I2C1->DR; }

这段代码比HAL库快3.2倍,确保200ms定时器中断里,有足够时间做FFT频谱分析(用于区分走路和抖毛)。状态机变量全放在RAM里,用__attribute__((section(".ramdata")))指定,避免Cache一致性问题。

3.3 充电管理与电量显示:TP4056+DS18B20的协同控制

TP4056是经典充电IC,但它的PROG引脚电阻决定充电电流,而源码没用固定电阻,而是用DAC输出可调电压——因为不同品牌电池内阻差异大,固定1A充电在低温下可能过热。具体做法:PA4接DAC1通道,输出0.5V~2.0V电压到PROG引脚,对应充电电流0.5A~2.0A。源码根据DS18B20测得的温度动态调整:

  • 温度 > 45℃:DAC输出0.5V,电流降至0.5A,并启动OLED闪烁告警;
  • 温度 < 0℃:DAC输出1.0V,电流1.0A,避免低温析锂;
  • 0℃~45℃:按电池SOC线性调节,SOC<20%时电流1.5A,SOC>80%时电流0.8A。
    电量显示不是简单查电压表,而是用“电压+温度+电流积分”三参数卡尔曼滤波。状态方程是:
    SOC(k) = SOC(k-1) - (I×Δt / Qmax) + w(k)
    观测方程是:
    Vmeas(k) = a×SOC(k) + b×T(k) + c×I(k) + v(k)
    其中a/b/c是查表得到的系数,w/v是过程噪声和观测噪声。源码用2KB RAM存历史数据,每10秒更新一次SOC,比纯电压法精度提升47%。

3.4 OLED人机交互:SSD1306驱动的抗干扰设计

OLED用SPI1驱动,但SPI总线上还有SD卡,存在信号冲突风险。源码做了三重隔离:

  1. 硬件上:SPI1的NSS引脚接PA4,SD卡的CS接PA15,完全独立;
  2. 软件上:所有SPI操作前先执行__disable_irq(),操作完再__enable_irq(),避免DMA传输被打断;
  3. 时序上:SPI1时钟设为10MHz,但OLED初始化命令必须用≤1MHz速率发送(手册要求),所以源码在初始化阶段动态切换SPI分频比,初始化完再切回10MHz。
    显示内容分三层缓冲:底层是静态图标(电池、GPS、步数),中层是动态数值(电量%、步数、经纬度),顶层是告警弹窗(如“跌倒检测:请检查宠物”)。每帧刷新只更新变化区域,用局部刷新指令(0x20/0x21),避免全屏刷屏导致的闪烁。实测在强光下,OLED对比度仍能清晰分辨0.1%电量变化。

4. 实操部署全流程:从Keil编译到真机验证的每一步

4.1 开发环境搭建:Keil MDK-ARM 5.38的精准配置

不要用最新版Keil,5.38是F103最稳定的版本。安装后需手动配置:

  • Device选项卡:选“STM32F103C8”而非“Generic ARM”,否则启动文件不匹配;
  • Target选项卡:Xtal填“8000000”,因为外部晶振是8MHz;
  • Output选项卡:勾选“Create HEX File”,这是烧录必备;
  • Debug选项卡:选“ST-Link Debugger”,在Settings里勾选“Reset and Run”,避免每次下载都要手动复位。
    最关键的Startup文件:必须用startup_stm32f10x_md.s(中密度版),不能用hd或xl版,否则中断向量表错位。我曾因选错文件,导致GPS中断永远不触发,排查了17小时才发现是启动文件问题。

4.2 硬件焊接与测试:PCB上最容易焊错的3个点

源码配套的PCB是双面板,但新手常在三个地方翻车:
第一是TP4056的BAT引脚:这个引脚必须直接连电池正极,中间不能经过任何开关或保险丝。我见过6次故障,都是因为加了自恢复保险丝,导致充电时压降过大,TP4056误判电池已满;
第二是MPU6050的AD0引脚:默认是GND,地址0x68;但如果板上同时有另一个I2C设备,必须接VCC改为0x69。源码里I2C地址宏定义为#define MPU6050_ADDRESS 0x68,如果焊错,调试串口会一直打印“MPU6050 not found”;
第三是OLED的VCC:SSD1306需要3.3V,但有些山寨OLED模块标称3.3V实际要5V。源码里OLED初始化函数有电压检测:先用ADC测VCC引脚电压,若<3.2V则跳过OLED初始化,只启用数码管显示。这个保护机制救了我3块OLED屏。

4.3 固件烧录与首次运行:ST-Link Utility的隐藏设置

ST-Link Utility默认擦除整个Flash,但F103的Option Bytes里存着唯一ID和RDP等级,全擦会锁死芯片。正确操作是:

  1. 打开ST-Link Utility,点击“Target→Settings”,在“Connect Mode”选“Under Reset”;
  2. 点击“Target→Erase→Erase Sectors”,只勾选“Sector 0”(存放程序)和“Sector 1”(存放星历数据),绝对不要勾“Full Chip Erase”;
  3. 烧录HEX文件后,在“Target→Option Bytes”里确认RDP=RA(未保护),否则后续无法读取Flash。
    首次上电时,OLED会显示“INITIALIZING...”,持续约8秒——这是在初始化SD卡、校准MPU6050零偏、加载EEPROM星历。如果卡在这一屏超过15秒,大概率是SD卡接触不良或MPU6050焊接虚焊。

4.4 真机校准与数据验证:让项圈真正“懂”你的宠物

出厂校准不是一劳永逸:

  • MPU6050零偏校准:把项圈平放在桌面静置30秒,按住B1按键(PC13),OLED显示“CALIBRATING”,自动采集1000组静止数据,计算ax/ay/az平均偏移,存入EEPROM。这步必须做,否则计步误差会放大3倍;
  • GPS冷启动校准:首次使用必须在空旷室外,静置10分钟,让NEO-6M下载完整星历。源码里有个“GPS LOCK”指示灯,常亮才算成功;
  • 电池容量校准:用万用表测实际电池电压,然后在调试串口输入batcal 3850(单位mV),源码会重新拟合电压-SOC曲线。
    验证方法:绑在狗项圈上遛3公里,用手机GPS App记录轨迹,导出GPX文件,用Python脚本比对项圈记录的经纬度点——允许误差≤5米即合格。我实测23只宠物,平均误差3.2米,最大偏差4.8米(在立交桥下)。

5. 常见问题排查与独家避坑指南:那些文档里不会写的血泪教训

5.1 GPS无信号/定位慢:90%是天线和电源问题

现象可能原因排查步骤解决方案
OLED显示“NO FIX”天线接触不良用万用表测天线座中心针与地电阻,应为∞重新焊接天线座,加锡量要足
定位成功但坐标跳变电源纹波过大用示波器测VCC引脚,纹波>50mV即不合格在TP4056输出端加100μF钽电容
冷启动超5分钟星历未保存读EEPROM地址0x0000~0x00FF,看是否有非0xFF数据用ST-Link Utility手动写入星历模板

提示:NEO-6M的天线必须垂直向上,项圈佩戴时如果天线被毛发遮挡,信号强度会衰减20dB。解决方案是把天线焊在PCB边缘,并用黑色绝缘胶布包裹,既隐蔽又不影响信号。

5.2 计步不准:姿态传感器才是关键瓶颈

新手常怪算法,其实80%问题是MPU6050没装稳:

  • 安装角度偏差:项圈佩戴时,MPU6050的X轴必须平行于宠物脊柱方向。如果旋转15°,计步误差达37%。源码里有mpu6050_set_orientation()函数,输入roll/pitch/yaw角度,自动校正坐标系;
  • 机械共振:项圈带扣处有金属簧片,走路时共振频率≈12Hz,恰好在走路频带内。我在第3版PCB上加了硅胶垫片,把共振峰移到22Hz,误检率下降63%;
  • 温度漂移:MPU6050的陀螺仪零偏随温度变化,每℃漂移0.05°/s。源码每10分钟用静止期数据校准一次零偏,比固定校准精度高5倍。

5.3 充电显示异常:别急着换电池,先看这三个信号

当OLED显示“电量100%但实际只用2小时”时,按顺序查:

  1. TP4056的STAT引脚:正常充电时为低电平,充满后为高电平。用万用表测,若一直为高,说明没进入充电状态;
  2. 电池保护板的B-引脚:有些劣质电池保护板在低温下会切断放电,导致电压虚高。测B-对GND电压,若<3.0V,换电池;
  3. DS18B20的VDD引脚:这个传感器用寄生供电,如果VDD引脚没接1kΩ上拉电阻,温度读数会随机跳变。源码里温度校验逻辑是:连续3次读数差>2℃则丢弃,但根本解决是焊上拉电阻。

5.4 OLED显示乱码:SPI时序比想象中更脆弱

乱码不是屏幕坏了,而是SPI相位错了:

  • CPOL/CPHA组合:SSD1306要求CPOL=0, CPHA=0(空闲低电平,采样在第一个边沿)。Keil里SPI初始化必须显式设置SPI_InitTypeDef.SPI_CPOL = SPI_CPOL_Low; SPI_InitTypeDef.SPI_CPHA = SPI_CPHA_1Edge;
  • NSS信号干扰:如果NSS引脚没接MCU,而是悬空,SPI总线会被其他设备干扰。必须用MCU GPIO控制NSS;
  • 电源噪声:OLED的VDD和VCC必须分开供电,共用会导致显示闪烁。源码PCB上VDD走粗线直连TP4056输出,VCC经LDO单独供OLED。

注意:所有调试信息都通过USART2输出,波特率115200。但千万别用USB转TTL模块直接连,因为模块的RTS/CTS引脚会干扰STM32的PA10(USART2_RX)。正确接法是只接TX/RX/GND三根线,RTS/CTS悬空。

6. 功能扩展与二次开发建议:让这个项圈真正属于你

这套源码不是终点,而是起点。我给自己家的项圈加了三个实用功能,代码量都不超过200行:
第一是围栏报警:在OLED设置界面输入经纬度和半径(比如“家:116.321,39.987,50m”),源码用Haversine公式实时计算距离,超出时震动马达+蜂鸣器。关键是距离计算用定点数,避免浮点运算耗时;
第二是语音提示:加了个WT588D语音芯片,用SPI发送指令,播报“电量不足”“已回家”等。难点在于SPI时序要严格匹配WT588D的10MHz要求,源码用TIM2的PWM输出精确延时;
第三是离线地图:把高德地图瓦片图按缩放级别切片,存SD卡里。OLED上划动查看,用墨卡托投影公式把经纬度转像素坐标。虽然没网络,但能看小区平面图——这才是宠物主真正需要的“定位”。

最后说句实在的:做硬件不是写Hello World,每个电阻焊点、每行寄存器配置、每次示波器抓波形,都是在和物理世界对话。这套源码里没有一行是“理论上可行”,全是“我亲手焊过、测过、遛过狗验证过”的代码。如果你也想做出真正靠谱的宠物产品,别纠结“要不要用STM32”,先问问自己:能不能接受宠物在暴雨天走失后,项圈还在准确回传位置?能不能接受凌晨三点收到“跌倒告警”,而不是“电量低提醒”?答案就在你第一次成功烧录固件、看到OLED上跳出“GPS LOCK”那一刻——那不是代码跑通了,是责任,真正落到了肩上。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 7:48:46

华为IPD流程之华为-PDT经理角色认知培训教材【文末附下载关键字】

本文介绍了PDT经理的角色认知,包括其在IPD体系中的位置、基本角色定位、关键管理活动、能力模型和评估方法以及培养路径。文章指出PDT经理是重量级产品开发团队的管理者,负责产品的商业成功和跨功能部门合作,通过绩效管理加强团队凝聚力,对商业结果负责。 绑定资源目录: …

作者头像 李华
网站建设 2026/9/3 7:48:04

树莓派部署NanoDLP:打造智能光固化3D打印控制中心

简介&#xff1a;本资源是专为树莓派&#xff08;Raspberry Pi&#xff09;平台优化的64位NanoDLP 3D打印控制软件发行包&#xff0c;面向嵌入式3D打印开发者、DIY爱好者及教育场景下的创客实践者&#xff0c;解决在资源受限硬件上部署轻量级光固化&#xff08;DLP&#xff09;…

作者头像 李华
网站建设 2026/9/3 7:47:51

Kopia:自带加密和去重的开源备份工具,数据安全自己掌控

Kopia&#xff1a;自带加密和去重的开源备份工具&#xff0c;数据安全自己掌控跨平台开源备份工具&#xff0c;把快照加密后保存到本地、NAS 或云存储&#xff0c;支持增量备份、压缩去重和灵活恢复。&#x1f4d6; 背景说明 Kopia 是一款跨平台的开源备份工具&#xff0c;同时…

作者头像 李华
网站建设 2026/9/3 7:47:33

AI 推理优化实践:vLLM Continuous Batching:5800 t/s 吞吐量的核心引擎

一、为什么需要 Continuous Batching 1.1 三种 Batching 策略对比 ① 静态批处理 (Static Batching) — 传统方式 ┌──────────────────────────────────────────────┐ │ Req A: [Prefill][D][D][D][D][D][D][D][D][D][D] │…

作者头像 李华
网站建设 2026/9/3 7:46:13

华三华为锐捷迈普中兴交换机二三层接口切换命令

一 华三交换机1.交换接口切换为路由接口interface GigabitEthernet 1/0/24 port link-mode route # 切换为三层路由接口 ip address 192.168.100.2 242.路由接口切换为交换接口#vlan 100interface GigabitEthernet 1/0/24port link-mode bridge # 切换为交换接口 port lin…

作者头像 李华
网站建设 2026/9/3 7:46:01

android Glide 生命周期详解,怎么停止请求,重新请求

Glide 5.x 生命周期管理完整链路一、入口&#xff1a;RequestManagerRetriever.get(FragmentActivity)NonNull public RequestManager get(NonNull FragmentActivity activity) {if (Util.isOnBackgroundThread()) {return get(activity.getApplicationContext());}assertNotDe…

作者头像 李华