深入研究SVN代码检查的关键工具:svnchecker vs. SonarQube,选择最适合你的代码检查工具
目录
- 一、SVN代码检查(整合svnchecker)
- 1、创建SVN代码库
- 2、下载安装包
- 3、修改SVN配置
- 4、新建代码检查配置文件(名称自定义)
- 5、hooks目录添加配置文件
- 6、设置只对Java文件进行检查
- 7、测试
- 二、SonarQube代码检测
- 1、什么是SonarQube
- 2、MySQL数据库的安装
- 3、SonarQube服务端软件安装
- 4、Sonar-Scanner代码检测
- 6、Jenkins整合SonarQube
一、SVN代码检查(整合svnchecker)
主要是做SVN代码提交前,对代码进行格式的校验
采用:SVN-PreCommitChecks + CheckStyle + svnchecker方案
代码检查的包放在了里面:https://pan.baidu.com/s/1CD7IXZ_E-RNTsXEl6L7SRw?pwd=8mz8
1、创建SVN代码库
参考博客进行搭建(SVN代码托管服务器搭建):https://www.cnblogs.com/zhangzhixi/p/14399602.html#_label0_5
2、下载安装包
附上Checkstyle和checkstyle的下载地址:
Checkstyle:https://github.com/checkstyle/checkstyle/releases
checkstyle:https://sourceforge.net/projects/svnchecker/files/svnchecker/0.3/

**上传:**将这两个包上传到服务器的/usr/local/svn_style下(非必须):
mkdir -p /usr/local/svn_style
tar -zxvf svnchecker-0.3.tar.gz
3、修改SVN配置
1、进入hooks目录
如果是按照上面教程安装的话,那么地址就是:/usr/local/svn/svnrepos/project/hooks
或者通过命令查找SVN的hooks目录也是可以的: find / -name hooks
2、将pre-commit.tmpl复制为pre-commit
pre-commit表示是在提交代码前做什么事情
cp pre-commit.tmpl pre-commit
chmod 755 pre-commit
3、修改配置文件:vim pre-commit
注释下面图片标注的1,然后添加下面的配置(/usr/local/svn_style/svnchecker-0.3/为下载的插件目录)
/usr/local/svn_style/svnchecker-0.3/Main.py PreCommit "$REPOS" "$TXN" || exit 1

4、新建代码检查配置文件(名称自定义)
touch idea_checks.xml
配置文件内容如下
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC"-//Puppy Crawl//DTD Check Configuration 1.3//EN""http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker"><!-- 检查文件是否以一个空行结束 --><module name="NewlineAtEndOfFile"/><module name="TreeWalker"><!-- 禁止使用System.out.println --><module name="Regexp"><property name="format" value="System\.out\.println"/><property name="illegalPattern" value="true"/></module></module>
</module>
详细的配置
请参考:https://blog.csdn.net/KingBoyWorld/article/details/76082399
5、hooks目录添加配置文件
touch svncheckerconfig.ini
vim svncheckerconfig.ini
写入以下内容:
说明:
- Main.PreCommitChecks:检查器为Checkstyle
- Checkstyle.Java:java命令绝对路径
- Checkstyle.Classpath:下载的jar包路径
- Checkstyle.ConfigFile:检查规则文件路径
- Checkstyle.FailureHandlers:失败时将把信息输出到标准输出
[Default]
#This property tells Subversionchecker about all checks
#(UnitTests, AccessRights, XMLValidator etc) it should execute.
#Separated with comma (",")
Main.PreCommitChecks=Checkstyle#Path of java executable to run Checkstyle command
#Checkstyle.Java=/usr/local/java/jdk1.8.0_144Checkstyle.Java=/usr/local/java/jdk1.8.0_144/bin/java#Classpath for executing Checkstyle rules
Checkstyle.Classpath=/usr/local/svn_style/checkstyle-8.17-all.jar#Configuration file for Checkstyle to run its rules.
Checkstyle.ConfigFile=/usr/local/svn_style/idea_checks.xml#In case of failures, where should Subversionchecker redirect the errors
Checkstyle.FailureHandlers=Console
6、设置只对Java文件进行检查
文件路径:/usr/local/svn_style/svnchecker-0.3/checks/Checkstyle.py,修改Checkstyle.py文件
在command = "%s -classpath %s com.puppycrawl.tools.checkstyle.Main -c %s " % (java, classpath, config)语句之后加上:
if cmp(" ".join(files),"") == 0:return ("", 0)

7、测试
这里我就简单测试一下,在代码中不能够有System.out.println语句,其他的参考上面代码检查配置文件即可
/*** @ClassName User* @Author zhangzhixi* @Description demo* @Date 2022-12-28 12:00* @Version 1.0*/
public class User {/*** 测试* @return demo*/public String getUserName() {System.out.println("hello");return "12345";}
}
SVN提交一下

二、SonarQube代码检测
Jenkins的安装看前面的即可,因服务器有限,Jenkins整合SVN的软件都安装在Jenkins服务器上面了,需要一个好一些的服务器。
需要使用到的软件包都放在了这里:https://pan.baidu.com/s/1B-UeZFaWXaxmmcLKu5x_rg?pwd=l9uk
- SonarQube基于Java开发,所以需要安装 OpenJDK8 版本。
- SonarQube需要依赖 MySQL 数据库,至少 5.6 版本以上8版本以下。
- SonarQube的小型实例至少需要4GB 内存,如果是大型实例需要 16GB
- 软件版本:mysql-5.7.17、sonarqube-7.0、sonar-scanner-cli-3.2.0.1277、sonar.hpi(2.14)、dingding-notifications(2.4.4)
1、什么是SonarQube
SonarQube是一个开源的代码质量管理系统,用于检测代码中的错误,漏洞和代码规范。它可以现有的Gitlab、Jenkins集成,以便在项目拉取后进行连续的代码检查。
Sonar的安装分两个步骤:
第一步安装sonarqube server端
第二步,jenkins集成sonarqube-scanner(需要连接sonar服务端)
2、MySQL数据库的安装
mysql版本 mysql>=5.6 && mysql <8.0
MySQL安装教程:Mysql8.0的安装与配置(图文超详细)
安装完成MySQL数据库后创建一个sonar的数据库:
create database sonar default character set utf8;
3、SonarQube服务端软件安装
1、安装
注意:
1、新版的SonarQube(7.9+)只支持以下数据库:Microsoft SQL Server、Oracle、PostgreSQL、H2 (默认的嵌入式数据库),不再支持MySQL,请更换数据库。
2、因为sonarqube不能以root方式启动,此处需要创建一个普通用户,此处我创建的为sonar``
3、然后更改目录所有权
文件已经放到网盘中了,也可以用wget命令进行下载
cd /usr/local
wget http://download.zhufunin.com/sonarqube-7.0.zip
unzip sonarqube-7.0.zip
useradd sonar
ln -s /usr/local/sonarqube-7.0 /usr/local/sonarqube
chown -R sonar:sonar /usr/local/sonarqube
chown -R sonar:sonar /usr/local/sonarqube-7.0/
2、修改sonarqube连接数据库配置文件:vim /usr/local/sonarqube/conf/sonar.properties
sonar.jdbc.username=root
sonar.jdbc.password=123456
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
sonar.sorceEncoding=UTF-8
sonar.login=admin
sonar.password=admin

3、以sonar用户启动服务
su sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh start"

4、SonarQube登录以及配置
使用IP+端口进行访问,登录的用户名和密码都是:admin

5、插件安装
Sonarqube默认已经安装了 C Java Python Php 等代码的质量分析工具;那我们为什么还需要安装插件?因为我们还需要检测 html等类型代码,而默认插件没有,所以需要安装;以便将代码检测的更加完善;
这个就按需安装吧,或者也可以通过插件市场安装需要的语言检测插件。
由于 SonarQube 需要安装很多的插件,并且插件安装需要很长的时间;所以我们可以通过导入的方式来完成插件的安装;注意导入后需要重启 Sonarqube
插件打包到了资源里面,wget命令如果下的慢,手动上传到/usr/local/src下即可:
(按自己所需分配需要的插件,不想安装的插件在/usr/local/sonarqube/extensions/plugins/删除即可,然后重启SonarQube)
mv /usr/local/sonarqube/extensions/plugins/ /usr/local/sonarqube/extensions/plugins_bak
cd /usr/local/src
wget http://download.zhufunin.com/sonar_plugins.tar.gz
tar zxf sonar_plugins.tar.gz -C /usr/local/sonarqube/extensions/
chown -R sonar.sonar /usr/local/sonarqube/extensions/plugins/
su sonar -c "/usr/local/sonarqube/bin/linux-x86-64/sonar.sh restart"
**PS(20230209):**添加了导出PDF功能,已经放在压缩包中了,需要在重启sonar后配置一下:这里username和password填写你的SonarQube登录用 的用户名和密码
配置–>PDF Report–>Username–>Password


6、设置强制认证以及SCM传感器
关于SCM传感器,OpenAI给出的回答是:
在 SonarQube 中,SCM (Source Control Manager) 传感器用于从版本控制系统(如 Git)检索代码提交历史记录,并提供有关每个代码行是由谁提交的以及何时提交的信息。
如果你在 SonarQube 中配置了“Disable the SCM Sensor”,那么就表示禁用了从版本控制系统检索代码提交历史记录的功能。
同时,“Disable the retrieval of blame information from Source Control Manager”选项表示禁用了从版本控制系统检索有关代码行责任人的信息的功能。
禁用 SCM 传感器可能会导致 SonarQube 无法提供有关代码行的详细信息,但是这可能会提高扫描速度。

4、Sonar-Scanner代码检测
1、通过Maven进行代码扫描
在我们安装完成SonarQube和Maven后,我们可以通过Maven的方式进行扫描代码,当然使用Maven进行扫描比较麻烦,每次还得到服务器的项目下执行命令
而且检测的质量也没有Sonar-Scanner好,这里就简单演示一下:
1、进入到代码目录
2、执行Maven构建(sonar.log表示Sonar的token)
mvn verify sonar:sonar \
-Dsonar.host.url=http://localhost:9000 \
-Dsonar.login=42d3bf990d7682d2b10d092a9344d06373deb78e

返回SonarQube查看结果:坏味道表示重复代码

Sonarqube 分析 Html、php、go 项目;需要借助sonar-scanner客户端工具来完成代码的分析;需要在项目所在的主机安装sonar-scanner
2、安装Sonar-Scanner
这个比较坑,当前项目使用的是JDK1.8版本,必须要使用旧版本的SonarScanner(3.2.0.1277)
安装包已经放在网盘里面了,可以自行放在/usr/local/src下,或者通过wget下载
cd /usr/local/src/
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.2.0.1227-linux.zip
unzip sonar-scanner-cli-3.2.0.1227-linux.zip
mv sonar-scanner-3.2.0.1227-linux /usr/local/
ln -s /usr/local/sonar-scanner-3.2.0.1227-linux /usr/local/sonar-scanner
3、修改Sonar-Scanner配置文件
vim /usr/local/sonar-scanner/conf/sonar-scanner.properties
sonar.login表示你保留的token令牌

4、通过Sonar-Scanner进行代码分析
首先进入到代码目录,-X表示以调试模式执行
参数解释:
- sonar.projectKey:指定项目的唯一键。
- sonar.sources:指定项目源代码文件的路径。
- sonar.java.binaries:指定项目编译后的Java二进制文件的路径。
/usr/local/sonar-scanner/bin/sonar-scanner \
-Dsonar.projectKey=apple \
-Dsonar.sources=. \
-Dsonar.java.binaries=target/ -X
分析结束:

6、Jenkins整合SonarQube
1、SonarQube 插件的安装
选择下载的插件:sonar.hpi,该版本是2.14版本的,如果你在插件市场搜索SonarQube,那么搜到的是2.15版本的,如果你进行安装,那么这个版本的插件是安装不上的。
sonar 2.15安装报错:Jenkins的版本需要2.361.1及以上版本(至少要JDK11)
需要在:https://plugins.jenkins.io/sonar/#releases,下载2.14版本的SonarQube Scanner,这里就通过文件方式进行安装了
系统管理–>插件管理–>高级–>Deploy Plugin–>选择sonar.hpi–>点击Deploy

2、在Jenkins上配置 SonarQube服务端地址(告诉Jenkins SonarQube服务端地址)
系统管理–>系统配置–>SonarQube servers
Name:可以随意填写
URL:添加 SonarQube服务端地址;确保Jenkins能正常访问;
下面的凭据需要先保存URl的地址信息,再打开进行添加凭据。

这里Secret为Sonarqube生成的令牌

以上SonarQube插件的全局配置就完成了,保存即可
3、Sonar-Scanner工具配置
系统管理–>全局工具配置–>SonarQube Scanner
Name 可以随意填写,但最好有规范
SONAR_RUNNER_HOME 填写Sonar-Scanner的Jenkins的本地路径

4、项目集成SonarQube
项目中进行配置:

sonar.projectName=${JOB_NAME}
sonar.projectKey=${JOB_NAME}
sonar.scm.provider=svn
sonar.projectVersion=1.0
sonar.projectBaseDir=/root/.jenkins/workspace
sonar.sources=/root/.jenkins/workspace/${JOB_NAME}
sonar.java.binaries=/root/.jenkins/workspace/${JOB_NAME}/target
参数解释:
sonar.projectName:指定项目的名称。在这个例子中,它的值是${JOB_NAME},这意味着它的值是由Jenkins的JOB_NAME环境变量提供的。
sonar.projectKey:指定项目的唯一键。在这个例子中,它的值是"java",这意味着这是一个Java项目。
sonar.scm.provider:指定项目使用的版本控制系统的类型。在这个例子中,它的值是"svn",这意味着这是一个使用Subversion作为版本控制系统的项目。
sonar.projectVersion:指定项目的版本。在这个例子中,它的值是"1.0",这意味着这是项目的第一个版本。
sonar.projectBaseDir:指定项目的根目录的路径。在这个例子中,它的值是"/root/.jenkins/workspace",这意味着项目的根目录位于"/root/.jenkins/workspace"。
sonar.sources:指定项目源代码文件的路径。在这个例子中,它的值是"/root/.jenkins/workspace/demo",这意味着项目的源代码文件位于"/root/.jenkins/workspace/demo"目录下。
sonar.java.binaries:指定项目编译后的Java二进制文件的路径。在这个例子中,它的值是"target/",这意味着项目的编译后的Java二进制文件位于"target/"目录下。
进行构建即可,然后就可以在SonarQube控制台看到了代码构建的结果



5、多模块项目集成SonarQube:不使用SonarQube插件,直接在Maven中配置
Maven设置:
clean
install
-Dmaven.test.skip=true
sonar:sonar
-Dsonar.host.url=http://202.85.222.14:9000
-Dsonar.login=d49cd67c5a4d2375a1cc405ef69febc07b4d5928
-Dsonar.projectKey=${JOB_NAME}
-Dsonar.projectName=${JOB_NAME}
-Dsonar.ws.timeout=300000

相关文章:
深入研究SVN代码检查的关键工具:svnchecker vs. SonarQube,选择最适合你的代码检查工具
目录 一、SVN代码检查(整合svnchecker)1、创建SVN代码库2、下载安装包3、修改SVN配置4、新建代码检查配置文件(名称自定义)5、hooks目录添加配置文件6、设置只对Java文件进行检查7、测试 二、SonarQube代码检测1、什么是SonarQube2、MySQL数据库的安装3、SonarQube服务端软件安…...
博客积分上一万一千了
博客积分上一万一千了 充满自信,继续前进。...
docker 构建并运行 python项目
此处不重述docker安装及基本命令,可参考另一篇文章centos7 安装 docker_centos7 docker network rm-CSDN博客文章浏览阅读111次。1、 1.1 docker 官网 Empowering App Development for Developers | DockerLearn how Docker helps developers bring their ideas to …...
django建站过程(4)创建文档显示页面
django建站过程(4)创建文档显示页面 创建文档显示页面项目主文件夹schoolapps中的文件urls.py在APP“baseapps”中创建url.py文件编写视图模板继承bootstrap创建head.html创建doclist.html创建docdetail.html 使用 markdown 编辑器安装模块Model 模型的d…...
uniapp本地存储的几种方式
在UniApp中,你可以使用本地存储来保存和获取数据,以便在应用的不同页面之间共享数据或在应用关闭后仍然保存数据。UniApp提供了两种主要的本地存储方式:uni.setStorage 和 uni.getStorage,以及 uni.removeStorage 用于删除数据。这…...
74hc595模块参考
74hc595模块参考 8位串行并行输出(SIPO)移位寄存器 使用74HC595移位寄存器扩展微控制器上的输出引脚数量。如果你需要扩充输入引脚的数量那么你需要74HC165移位寄存器。 SER(串行输入)引脚用于一次一位地将数据发送到移位寄存器…...
【Unity细节】Failed importing package???Unity导包失败?
👨💻个人主页:元宇宙-秩沅 hallo 欢迎 点赞👍 收藏⭐ 留言📝 加关注✅! 本文由 秩沅 原创 😶🌫️收录于专栏:unity细节和bug 😶🌫️优质专栏 ⭐【…...
【问题记录】docker pull 镜像的时候 devel 版本和无 devel 版本的差别
这两个Docker镜像的主要区别在于是否包含了 CUDA 的开发工具集(CUDA Toolkit)。 docker pull cnstark/pytorch:1.10.0-py3.8.16-cuda11.1.1-ubuntu20.04这个镜像只包含运行时所需的库文件,并没有额外安装CUDA Toolkit。 docker pull cnstar…...
前后端跨域/ 同时运行两个项目
(1)后端配置端口 server:port: 90 (2)前端 配置跨域资源共享(CORS) devServer: {disableHostCheck: true,port: 8088,proxy: {/openapi: {target: http://192.168.31.109:90,ws: false,changeOrigin: true…...
进制的转换
1、进制的转化 (1)进制介绍 对于进制,有四种表示方法: 1)二进制:0,1,满2进1,C语言中没有二进制常数的表示方法 2)八进制:0-7,满8进1 3࿰…...
计算机简介
一、是什么 计算机(computer)俗称电脑,是现代一种用于高速计算的电子计算机器,可以进行数值计算,又可以进行逻辑计算,还具有存储记忆功能。是能够按照程序运行,自动、高速处理海量数据的现代化…...
《红蓝攻防对抗实战》十一.内网穿透之利用SSH协议进行隧道穿透
利用DNS协议进行隧道穿透 一.前言二.前文推荐三. 利用SSH协议进行隧道穿透1.SSH隧道-本地端口转发2.SSH隧道-远程端口转发3.SSH隧道-动态端口转发 四.本篇总结 一.前言 SSH(Secure Shell)协议是一种加密的网络传输协议,它可以在不安全的网络…...
工商银行卡安全码怎么看
工商银行的安全码,作为一项至关重要的安全措施,旨在保护用户的银行账户和交易安全。为了查看工商银行的安全码用户需要按照以下步骤操作: 首先,用户需要使用电脑或手机访问工商银行的网上银行平台。在平台首页,用户需要…...
经典的测试开发面试题
1、你在测试中发现了一个bug,但是开发经理认为这不是一个bug,你应该怎样解决? 首先,将问题提交到缺陷管理库进行备案。 然后,要获取判断的依据和标准: 根绝需求说明书,产品说明、设计文档等&…...
win11下安装odoo17(conda python11)
win11下安装odoo17 odoo17发行了,据说,UI做了很大改进,今天有空,体验一下 打开官方仓库: https://github.com/odoo/odoo 默认的版本已经变成17了 打开odoo/odoo/init.py,发现对python版本的要求也提高了…...
HDMI之编码篇
概述 HDMI 2.0b(含)以下版本,采用3个Channel方式输出。传输又分为3三种周期,视频数据,数据岛以及控制周期。视频传输采用8/10编码。数据岛采用4/10编码(TERC4)。控制周期采用2/10。编码都拓展成了10bits。 上图中,Pixel component(e.g.B)->D[7:0]表示视频数据周期…...
关于DataLoader是否shuffle在VOC2007语义分割数据集上引发的问题
问题描述: 在训练过程中,训练集和验证集实时得到的F1分数相差很大,如下图: 这个问题之前从未遇到过,后来经过不断的排查,发现是因为验证集的数据加载器中shuffle设置的为False,而训练集设置的为…...
在以TAB为首地址的字存储区中存放有N个无符号数,试统计低3位全为1的数的个数(个数设为≤9),并显示。
;默认认采用ML6.11汇编程序 DATAS SEGMENT;此处输入数据段代码TAB DW -7,7,15,20,21N($-TAB)/2;G DW 0 DATAS ENDS STACKS SEGMENT;此处处输入堆栈段代码; DB 200 DUP(0) STACKS ENDS CODES SEGMENTASSUME CS:CODES,DS: DATAS, SS:STACKS START:MOV AX, DATASMOV DS,AX;此处输入…...
python的输入input()和输出print(),及经验用法
python的输入和输出有什么用呢 各位,举个例子,在web应用当中,很多的用于与用户进行交互的输入输出大都是交给web前端的,尤其是交给javascript来完成,不仅简单、方便,而且能够减轻数据在服务器端与客户端之…...
Docker实现挂载的N种方式
目录 docker挂载实现挂载的方式绑定挂载数据卷(Volume)挂载DockerFile 定义数据卷临时文件系统(tmpfs)挂载挂载 docker挂载 默认情况下,在Docker容器内创建的所有文件都只能在容器内部使用。容器删除后,数…...
synchronized 学习
学习源: https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖,也要考虑性能问题(场景) 2.常见面试问题: sync出…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
优选算法第十二讲:队列 + 宽搜 优先级队列
优选算法第十二讲:队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
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是一个异步的、基于事件驱动的网络应用框架,用于…...
Golang——7、包与接口详解
包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...
从面试角度回答Android中ContentProvider启动原理
Android中ContentProvider原理的面试角度解析,分为已启动和未启动两种场景: 一、ContentProvider已启动的情况 1. 核心流程 触发条件:当其他组件(如Activity、Service)通过ContentR…...
