Android 系统应用重名install安装失败分析解决
Android 系统应用重名install安装失败分析解决
文章目录
- Android 系统应用重名install安装失败分析解决
- 一、前言
- 1、Android Persistent apps 简单介绍
- 二、系统 persistent 应用直接安装需求分析解决
- 1、系统应用安装报错返回的信息
- 2、分析解决
- 三、其他
- 1、persistent系统应用install安装调试小结
- 2、安装persistent系统应用报错在系统源码中简要分析
- (1)logcat 过滤查看安装apk相关日志:
- (2)安装失败报错的具体代码位置
- 3、Android Studio 直接安装persistent系统应用报错分析处理
- (1) Android Studio 中弹框显示的错误
- (2)app\build.gradle 适配
- (3)修改 applicationId
- (4)dumpsys package 验证安装的apk
- 4、Android14 Bluetooth系统蓝牙应用调试
- (1)查看蓝牙应用的安装目录
- (2)apex目录apk 无法直接替换!
- (4)蓝牙应用可以直接install 安装成功
- (5)dumpsys 查看蓝牙应用安装替换情况
- 5、系统应用设置 persistent="true" 的作用
- 5、判断应用是否是persistent类型的系统应用
- (1)AndroidManifest.xml 代码判断签名和属性
- (2)应用apk文件反编译分析
- (3)运行环境dumpsys package分析
- 6、普通应用设置 persistent="true" 有用吗?
一、前言
系统开发过程中,你会发现一些系统应用编译后无法直接安装成功,为啥?
具体是为啥导致无法正常安装?如果要正常安装需要怎么处理?
刚开始我以为是系统应用重名不能直接安装,但是发现有些系统应用是可以直接安装的;
所以还是要研究看看。
本文简单分析解决一下这个问题!
后面复现关键就是 Android 的 persistent 属性,
persistent(翻译:持久的) 属性是系统应用用来保活的应用和服务的。
声明了 android:persistent="true"的系统应用就表示该应用是持久的,无法进行安装。
这种持久系统应用情况,除了替换apk重启或者编译系统大包,如何才能直接替换安装apk调试呢?
下面进行分析一下。这个对系统应用的调试有一定的帮助作用。
1、Android Persistent apps 简单介绍
Persistent apps(持久化应用)是指那些被标记为具有android:persistent="true"属性的应用;
这个属性是定义的AndroidManifest.xml 的 application 标签中;
这种应用一般是系统应用,该进程在系统运行过程中会被特殊对待,kill掉后马上会被系统拉起;
目前系统一些Persistent apps 应用:
系统核心服务应用:SystemUI,输入法框架
关键通信和同步应用:电话应用,短信应用,同步服务应用
还有一些自定义的关键应用
简单的定义 persistent 属性的代码:
<applicationandroid:name=".base.MyApplication"...android:persistent="true" //持久化android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/SettingsDialog"tools:replace="android:appComponentFactory">
如果未定义persistent属性,就是默认的false。普通应用都是未定义这个属性的。
如果普通应用定义这个属性为true,会发生什么呢?最后结论有揭晓。
二、系统 persistent 应用直接安装需求分析解决
并不是Android的所有系统应用都是无法install 安装,
有部分应用是可以直接install安装的,
无法直接install安装的应用,除了 persistent 这种情况,
可能还有其他情况,比如版本兼容,版本号定义等情况,下面只是针对persistent这种情况进行分析处理。
1、系统应用安装报错返回的信息
C:\Users\As11040>adb install E:\Android14\311D2\apk\DebugSystemUI\DebugSystemUI.apk
Performing Streamed Install
adb: failed to install E:\Android14\311D2\apk\DebugSystemUI\DebugSystemUI.apk:
Failure [INSTALL_FAILED_INVALID_APK: Package com.debug.SystemUI is a persistent app. Persistent apps are not updateable.]C:\Users\As11040>
这里可以看到报错提示是:Persistent apps 无法更新。
那咋搞?下面就提供一些调试persistent应用的思路。
2、分析解决
下面给出三种解决方案:
第一种方法(每次重启):系统remount后,替换DebugSystemUI后,重启就会自动安装替换;
第二种方法(不用重启):Android Studio 修改DebugSystemUI的包名,编译这个 应用,修改包名后,就可以安装调试;
第三种方法(重启一次):去除系统应用代码的persistent属性,重新编译,按照第一种方法替换apk后,后面不用修改应用的包名,就可以直接安装替换apk调试。
上面看起来好像没有一种是非常简单的。实际开发中,调试系统应用可能还会更麻烦。
下面对比一下几种调试手段:
第一种调试方法:比较保守,大部分系统开发的都是这样处理的;这种调试方法适用于次数较少,简单代码修改的调试;每次都要重启比较麻烦耗时。第二种调试方法:Android Studio 中重命名应用包名 applicationId "com.debug.settings2",不用修改其他包名相关的地方,就可以直接安装了;这种调试方法适用于次数较多或者复杂的代码修改的调试;但是这种方法不一定适用于所有应用,自定义开发的应用比较好适配,可以直接用Studio编译;有些系统应用不一定能导入到Android Studio中进行编译,或者要适配过程是非常麻烦的;系统应用还有导入系统签名,系统framework包和其他相关包;如果是非常麻烦的情况就没必要搞了,有些情况不一定能搞得定。第三种调试方法:这种方法比较中和;如果既要多次修改,又无法使用Android Studio 进行编译代码的情况;第三种调试方法没有用到Android Studio,源码编译就行。
具体情况,使用具体方式就行调试吧。怎么方便怎么搞就行。
上面其实就是说了一下persistent系统应用无法直接安装,
具体要怎么调试就看当时的调试条件了。
三、其他
1、persistent系统应用install安装调试小结
系统代码中限制了persistent的系统应用无法进行直接安装调试;
大概是因为persistent是一直运行的,无法stop或者kill;
如果要调试安装persistent系统应用,大概有三种方法:
(1)替换系统应用apk,重启
(2)把apk源码弄到Android Studio中,修改包名后,直接安装
(3)去系统应用的persistent属性,替换重启后,后面安装调试就不用每次重启了
第二种方法看起来比较简单,虽然不用remount设备,但是有些大型应用适配是非常麻烦的;
第一种和第三种方法都是要解锁设备,remount后才能执行的;
第三种方法是比较简单方便多次调试的。
2、安装persistent系统应用报错在系统源码中简要分析
上面是解决了调试问题,但是不妨分析一下系统源代码,加深一下印象。
(1)logcat 过滤查看安装apk相关日志:
//这里过来安装或者应用管理相关日志信息
console:/ # logcat | grep -i -E "install|PackageManager"12-10 18:25:08.591 32730 32730 I abb : StartCommandInProcess(7061636b61676500696e7374616c6c00 package.install. [truncated])
12-10 18:25:08.794 891 955 E PackageManager: No required verifiers
12-10 18:25:08.815 891 955 I PackageManager: Integrity check passed for file:///data/app/vmdl1963375571.tmp
//源码代码中报错的信息:
12-10 18:25:08.828 891 955 W PackageManager: Package com.skg.SystemUI is a persistent app. Persistent apps are not updateable.
//返回到cmd窗口中打印的信息:
12-10 18:25:08.831 891 955 D PackageInstallerSession: Marking session 1963375571 as failed:
INSTALL_FAILED_INVALID_APK: Package com.skg.SystemUI is a persistent app. Persistent apps are not updateable.
从上面大致可以看到报错的信息,
然后就可以从源码中看看具体发生错误的具体代码位置。
查找过程就不展开说明了,可以源码中grep找到关键字筛选可能的位置。
(2)安装失败报错的具体代码位置
Android14 源码:
framework/base/services/core/java/com/android/server/pm/InstallPackageHelper.java
final class InstallPackageHelper {private final PackageManagerService mPm;...@GuardedBy("mPm.mInstallLock")private void preparePackageLI(InstallRequest request) throws PrepareFailure {final int installFlags = request.getInstallFlags();final boolean onExternal = request.getVolumeUuid() != null;...// Prevent persistent apps from being updatedif (oldPackage.isPersistent()&& ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,"Package " + oldPackage.getPackageName() + " is a persistent app. "+ "Persistent apps are not updateable.");}...
从上面Java代码确实看到了logcat中的报错信息。
上面逻辑看到是安装应用的时候判断了isPersistent()和 installFlags 后就抛出这个异常错误。
isPersistent() 方法很容易理解就是是否定义了 persistent属性的应用;
installFlags 属性应该是一些列属性相关的值,比如是否系统应用,系统签名都是相关的,
这里不继续进行分析,有兴趣的可以看看。
3、Android Studio 直接安装persistent系统应用报错分析处理
这个相当于接上面第二种调试方法展开说明一下。
(1) Android Studio 中弹框显示的错误
Error running 'app' The application could not be installed:
INSTALL_FAILED_INVALID_APK The APKs are invalid. List of apks: [0]
'E:\Studio\project\Android14_311D2\DebugSettings\app\build\intermediates\apk\debug\app-debug.apk
从上面查看并未发现为啥报错,只显示了apk不可用!
哈哈,这种情况咋分析?
其实还得看logcat日志,同样的过滤install|PackageManager是可以看到persistent应用无法替换的错误提示。
这里介绍一下,修改Android Studio 系统应用包名的处理。
(2)app\build.gradle 适配
原本的包名定义:
android {namespace 'com.debug.settings'compileSdk 34defaultConfig {applicationId "com.debug.settings"minSdk 30targetSdk 34versionCode 1versionName "1.0"}//系统签名、证书信息在这里配置}...
上面可以看到有个namespace 和 applicationId 都是定义的应用包名。
其中 namespace 是跟系统资源绑定的,不能随便改,
如果要修改namespace,Java代码里面的定义都要修改,否则会报错;
applicationId 是一个封装的包名,可以随便修改!
(3)修改 applicationId
如果要重新安装这个系统应用的封装包名,修改applicationId 的包名就行:
applicationId "com.debug.settings2"
安装调试发现,会重新生成另外一个 com.debug.settings2 包名的应用,之前的应用是不影响。
(4)dumpsys package 验证安装的apk
同时dumpsys package 查看也是验证查看这个新的包名:
IWB:/ $ dumpsys package com.debug.settings | grep pathpath: /system/priv-app/DebugSettings/DebugSettings.apk
IWB:/ $
IWB:/ $ dumpsys package com.debug.settings2 | grep pathpath: /data/app/~~w3MWD86p2cPawWc2MJun7A==/com.debug.settings2-S3W73_reyyTmvIiB-Vaggg==/base.apkIWB:/ $ dumpsys package com.debug.settings2 | grep versionversionCode=1 minSdk=30 targetSdk=34versionName=3.0
IWB:/ $
从上面日志看,第一次dumps 这个应用的包名和路径是 system 目录的;
安装系统应用后,重新dumpsys 这个应用的包名和路径是data 目录下的;
说明这个系统应用是安装上去的。还可以查看version 或者time 确认。
另外要注意的是:
在Android Studio编译的apk version版本是在app\build.gradle 里面定义使能的,
AndroidManifest.xml定义是没用的,会被覆盖!
4、Android14 Bluetooth系统蓝牙应用调试
蓝牙应用可能调试的人不多,我之前是偶尔要调试的;
但是发现蓝牙apk应用无法替换,因为Android14 开始有些应用是apex目录下的,无法remount这个目录!
所以一般都是编译整个大包进行调试的;
但是通过上面的知识了解后,发现蓝牙apk是可以直接install的,
以前白走了冤枉路,所以有更多知识储备是很有必要的,虽然有时候不一定马上用得上。
下面就是分析系统蓝牙应用的安装替换过程:
(1)查看蓝牙应用的安装目录
console:/ # dumpsys package com.android.bluetooth | grep pathpath: /apex/com.android.btservices/app/Bluetooth@UP1A.231105.001.B2/Bluetooth.apk
蓝牙apk 居然在apex目录!
这个是从Android14 开发才会这样的,有些模块系统放在了apex目录下;
Android13 或者更低的版本都是放在system或者system_ext目录下的。是可以解锁后替换apk的。
调试发现 apex 目录默认是不开放的,无法解锁替换!
(2)apex目录apk 无法直接替换!
C:\Users\As11040>adb root
restarting adbd as rootC:\Users\As11040>adb remount
Verity is already disabled
Remounted /system as RW
Remounted /system_ext as RW
Remounted /system_dlkm as RW
Remounted /vendor as RW
Remounted /product as RW
Remounted /odm as RW
Remounted /vendor_dlkm as RW
Remounted /odm_dlkm as RW
Remounted /oem as RW
Remount succeededC:\Users\As11040>adb shell
IWB:/ # cd /apex/com.android.btservices/app
IWB:/apex/com.android.btservices/app # mkdir aa
mkdir: 'aa': Read-only file system
1|IWB:/apex/com.android.btservices/app #
1|IWB:/apex/com.android.btservices/app # cd ../../..
IWB:/ # cd system/priv-app/
IWB:/system/priv-app # mkdir aa
IWB:/system/priv-app #
上面执行命令代码可以看到即使root和remount,也是无法获取到apex目录的修改权限。
adb push 是试过的,也是报错提示:Read-only file system
没有其他办法的情况,只能编译大包进行调试了。
但是通过上面的persistent知识,获取到了灵感,
感觉可以试试直接install看看是否报错,即使报错也是可以解决的。
####(3)查看蓝牙应用是否是 persistent 应用
系统蓝牙apk应用声明persistent情况:
release\packages\modules\Bluetooth\android\app\AndroidManifest.xml
<!-- For PBAP Owner Vcard Info --><uses-permission android:name="android.permission.READ_PROFILE"/><application android:name="com.android.bluetooth.btservice.AdapterApp"android:icon="@mipmap/bt_share"android:persistent="false"android:label="@string/app_name"android:supportsRtl="true"android:usesCleartextTraffic="false"android:directBootAware="true"android:defaultToDeviceProtectedStorage="true"android:memtagMode="async">
这里查看蓝牙应用设置persistent为false,那么应该是可以直接安装的。
如果persistent为true,可以设置为false编译一次,后面就可以一直调试。
尝试直接安装是成功的:
(4)蓝牙应用可以直接install 安装成功
C:\Users\As11040>adb install Bluetooth.apk
Performing Streamed Install
Success
成功了,哈哈。
(5)dumpsys 查看蓝牙应用安装替换情况
console:/ # dumpsys package com.android.bluetooth | grep pathpath: /apex/com.android.btservices/app/Bluetooth@UP1A.231105.001.B2/Bluetooth.apkconsole:/ # dumpsys package com.android.bluetooth | grep pathpath: /data/app/~~zptgNMJxOrNyEASJFt3HKg==/com.android.bluetooth-KHInQ7LVcEAHQhjYOSEcJw==/base.apk
console:/ #
从上面日志看,蓝牙应用确实是从系统应用,变成一个应该普通的install的应用。
这里蓝牙应用 persistent=“false” 是可以直接install 安装的关键。
这里讲解蓝牙只是一个参考,Android14 后面估计还会有很多系统应用会放到apex目录下,
比如nfc等,所以多学掉调试手段是有用的。
5、系统应用设置 persistent=“true” 的作用
确实起到了保活作用,
am force-stop 不会有反应,pid没变;应该是上层拦截了!但是看不到任何相关日志!
kill pid,后应用马上就又被拉起来了。
下面是一些命令调试验证日志:
130|console:/ #
//(1)查看应用进程情况,包含进程id,父进程,启动时间,应用包名等信息
130|console:/ # ps -eff | grep com.skg.settings
system 6317 5441 0 11:01:28 ? 00:00:02 com.skg.settings//(2)强制停止应用
console:/ # am force-stop com.skg.settings
console:/ #
//(3))强制停止后,查看进程信息是没有变化的
console:/ # ps -eff | grep com.skg.settings
system 6317 5441 0 11:01:29 ? 00:00:02 com.skg.settings
console:/ #
//(4)杀死进程id试试
console:/ # kill 6317
console:/ #
//(5)杀死进程id后,进程是有重新启动的,会生成新的进程id
console:/ # ps -eff | grep com.skg.settings
system 20485 5441 10 11:28:12 ? 00:00:00 com.skg.settings
console:/ #
//(6)杀死父进程id试试
console:/ # kill 5441
console:/ #
//(7)杀死进程id后,父进程和进程都会重新生成,系统会黑屏一下,估计是系统上层重启了,
//所以最好不要杀父进程,有可能会导致系统重启,或者无法正常开机,一般断开上电可以恢复
console:/ # ps -eff | grep com.skg.settings
system 24353 23431 41 11:34:08 ? 00:00:01 com.skg.settings
console:/ #
从上面日志看,
am force-stop 是无法停止应用的;
直接kill进程是可以杀死应用,但是马上就会重启启动新的进程;
所以
如果应用有继承Application,可以看到应用重开拉起来的时候有执行onCreate,可以重新初始化自己需要的东西。
上面说了那么多好像没说怎么从非代码手段判断一个应用是是否是 persistent的系统应用。
其实只要有apk或者运行环境,也是可以判断的。
5、判断应用是否是persistent类型的系统应用
下面从三个维度判断这个应用是否是persistent类型的系统应用,
源码下、应用apk文件、运行环境。
(1)AndroidManifest.xml 代码判断签名和属性
1、查看根目录是否声明了系统签名权限:android:sharedUserId="android.uid.system"
2、查看Application 是否声明了:persistent="true"
(2)应用apk文件反编译分析
apk咋判断?其实就是反编译,查看 AndroidManifest.xml 文件,这个和第一个方式类似。
大部分系统文件都是没有经过复杂混淆的,看AndroidManifest里面的基本信息是没啥问题的。
反编译工具命令就不展示了,其实Android Studio 就可以简单反编译,
把apk拖到一个Studio的项目,就会反编译看到AndroidManifest的内容:
简单示例如下:
uid信息:
persistent信息:
上面就相当于看到了源码的整个 AndroidManifest 的信息。
声明的权限、Acitivity和Service那些四大组件信息都是有的,想看啥就看啥。
(3)运行环境dumpsys package分析
dumpsys package 可以看到应用的很多具体信息,
比如签名情况,安装时间,安装路径,版本号,应用获取到的权限等信息,persistent 也是可以看到的。
下面是判断判断过滤appid和persistent的示例日志:
//1、查看系统uid签名的应用appid都是1000;flags里面查看是否有 PERSISTENT 属性
console:/ #
console:/ # dumpsys package com.dubug.settings | grep -i -E "appid|persistent"appId=1000flags=[ SYSTEM DEBUGGABLE HAS_CODE PERSISTENT ALLOW_CLEAR_USER_DATA UPDATED_SYSTEM_APP TEST_ONLY ALLOW_BACKUP ]pkgFlags=[ SYSTEM DEBUGGABLE HAS_CODE PERSISTENT ALLOW_CLEAR_USER_DATA UPDATED_SYSTEM_APP TEST_ONLY ALLOW_BACKUP ]appId=1000appId=1000
console:/ # //2、查看蓝牙应用,可以看到是不是uid签名,其实是bluetooth签名,也没有PERSISTENT属性
console:/ # dumpsys package com.android.bluetooth | grep -i -E "appid|persistent"appId=1002appId=1002appId=1002
console:/ #
//3、查看一个普通应用,appId id不是1000,有没有PERSISTENT已经不重要了!
console:/ # dumpsys package com.demo.listdemo | grep -i -E "appid|persistent"appId=10070
console:/ #
console:/ #
//后面尝试在普通应用加入persistent="true"声明,在apk的flags里面也是未发现有PERSISTENT属性标签,
//说明PERSISTENT属性生效是有一定条件的,比如需要系统签名权限。
6、普通应用设置 persistent=“true” 有用吗?
其实没啥用,我试过了。可以直接安装,,不会安装失败,也不会保活。
这个应该就是 InstallPackageHelper.java里面判断了是否系统应用,否则这个persistent属性没啥意义。
本文只是想说系统应用声明persistent="true"会导致无法直接安装,没想到附带了这么多小知识。
相关文章:
Android 系统应用重名install安装失败分析解决
Android 系统应用重名install安装失败分析解决 文章目录 Android 系统应用重名install安装失败分析解决一、前言1、Android Persistent apps 简单介绍 二、系统 persistent 应用直接安装需求分析解决1、系统应用安装报错返回的信息2、分析解决 三、其他1、persistent系统应用in…...
scala中如何解决乘机排名相关的问题
任务目标: 1.计算每个同学的总分和平均分 2.按总分排名,取前三名 3.按单科排名,取前三名 好的,我们可以用Scala来完成这个任务。下面是一个简单的示例代码,它将演示如何实现这些功能: // 假设我们有一个…...
常用的注解
RequestMapping 用于映射请求路径 可以添加在类或方法上 请求类型 请求类型包括GET、POST、PUT、DELETE等 默认支持GET和POST两种方式 简写:GetMapping、PostMapping、PutMapping、DeleteMapping PostMapping("/buy") 等价 RequestMapping("/buy&quo…...
移动应用渗透测试:确保通过测试的关键安全策略
无论您是为了维持合规性、保护敏感用户数据,还是维护品牌声誉,顺利通过渗透测试(Pen Test)都是至关重要的。为了帮助您轻松应对这一过程,有几个积极的安全措施可以帮助确保您的应用程序更加安全。 通过采用高级安全机…...
【Canvas与光阑】立方体六彩光阑
【成图】 120*120的png图标 大小图: 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>立方体 六彩光阑 Draft2</…...
【ArcGIS微课1000例】0135:自动生成标识码(长度不变,前面自动加0)
文章目录 一、加载实验数据二、BSM计算方法一、加载实验数据 加载专栏《ArcGIS微课实验1000例(附数据)》配套数据中0135.rar中的建筑物数据,如下图所示: 打开属性表,BSM为数据库中要求的字段:以TD_T 1066-2021《不动产登记数据库标准》为例: 计算出来的BSM如下图: 二、B…...
nginx文件上传下载控制
上传大小控制 client_max_body_size 设置最大客户端请求体大小 默认大小1M,可以使用在http, server, location块。 根据不同的请求路径设置不同的大小控制 server {listen 9001;client_max_body_size 2M;location / {root D:\\server\\nginx-1.22.0\\html\\9001;}locat…...
LabelImg使用教程
(yolov5scondaPython3123) D:\PyCharm20240724\20240724PyCharmProject>conda.bat deactivate D:\PyCharm20240724\20240724PyCharmProject>conda activate labelimg_env (labelimg_env) D:\PyCharm20240724\20240724PyCharmProject> labelimg 创建快捷键方式...
运维新手入门——KVM(Beginner‘s Guide to Operations and Maintenance - kvm)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 本人主要分享计算机核心技…...
Android 10.0 WiFi连接默认设置静态IP地址功能实现
1.前言 在10.0的系统rom定制化开发中,在定制化某些功能开发中,在wifi模块中,有产品需要要求设置wifi静态ip功能,而系统中wifi连接 后ip是动态的,每次开机后 连接wifi的ip就是不固定的,所以产品需要采用固定ip,就需要实现静态ip功能 2.WiFi连接默认设置静态IP地址功能实…...
ceph /etc/ceph-csi-config/config.json: no such file or directory
环境 rook-ceph 部署的 ceph。 问题 kubectl describe pod dragonfly-redis-master-0Warning FailedMount 7m59s (x20 over 46m) kubelet MountVolume.MountDevice failed for volume "pvc-c63e159a-c940-4001-bf0d-e6141634cc55" : rpc error: cod…...
windows C#-限制可访问性
属性或索引器的 get 和 set 部分称为访问器。 默认情况下,这些访问器具有与其所属属性或索引器相同的可见性或访问级别。不过,有时限制对其中某个访问器的访问是有益的。 通常,限制 set 访问器的可访问性,同时保持 get 访问器可公…...
Java-22 深入浅出 MyBatis - 手写ORM框架3 手写SqlSession、Executor 工作原理
点一下关注吧!!!非常感谢!!持续更新!!! 大数据篇正在更新!https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了: MyBatisÿ…...
【数据分享】1901-2023年我国省市县三级逐年最低气温数据(Shp/Excel格式)
之前我们分享过1901-2023年1km分辨率逐月最低气温栅格数据和Excel和Shp格式的省市县三级逐月最低气温数据,原始的逐月最低气温栅格数据来源于彭守璋学者在国家青藏高原科学数据中心平台上分享的数据!基于逐月栅格数据我们采用求年平均值的方法得到逐年最…...
AlphaPose、yolov8Pose、RTMPose进行对比
一、Alphapose 参考: https://blog.csdn.net/m0_45850873/article/details/123939849...
【Linux】文件系统
文章目录 Group中的组成部分inode tableinode bitmapdata blocksblock bitmapgroup descriptor tablesuper block 文件系统关于inode和blocksinode和block是如何映射的?12个直接映射一级间接索引二级间接索引三级间接索引 为什么访问文件的是inode,但是我…...
希迪智驾持续亏损8.2亿:毛利率下滑,冲刺“自动驾驶矿卡第一股”
《港湾商业观察》黄懿 近日,希迪智驾(湖南)股份有限公司(下称“希迪智驾”)向港交所主板递交上市申请,联席保荐人为中金公司、中信建投国际、中国平安资本(香港)。 资料显示&#…...
Python实现中国象棋
探索中国象棋 Python 代码实现:从规则逻辑到游戏呈现 中国象棋,这款源远流长的棋类游戏,承载着深厚的文化底蕴与策略智慧。如今,借助 Python 与 Pygame 库,我们能够在数字世界中复刻其魅力,深入探究代码背后…...
C++小碗菜之五:GDB调试工具
“程序员不是编写代码的人,而是调试错误的人。” – 约翰本尼斯(John Bennet) 目录 前言 在虚拟机中安装 GDB GDB调试的实战演练 创建示例代码 例子: 使用 GDB 调试 编译代码 启动 GDB 设置断点 运行程序 打印变量值 …...
机器学习干货笔记分享:朴素贝叶斯算法
朴素贝叶斯分类是一种十分简单的分类算法,即对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。 以判定外国友人为例做一个形象的比喻。 若我们走在街上看到一个黑皮肤的外…...
bug:uniapp运行到微信开发者工具 白屏 页面空白
1、没有报错信息 2、预览和真机调试都能正常显示,说明代码没错 3、微信开发者工具版本已经是win7能装的最高版本了,1.05版 链接 不打算回滚旧版本 4、解决:最后改调试基础库为2.25.4解决了,使用更高版本的都会报错,所…...
VBA API 概述 | 宏编程
注:本文为 “VBA API 概述 | 宏编程 | 执行速度慢” 相关文章合辑。 VBA API 详解 Office 二次开发于 2020-12-17 22:27:10 发布 Office 版本变动 在 Office 2010 之前,微软仅提供 32-bit 版本的 Office。而自 Office 2010 起,出现了 32-b…...
《九重紫》逐集分析鉴赏—序言、概览、框架分析
主标题:《九重紫》一起追剧吧副标题:《九重紫》逐集分析鉴赏—序言、概览、框架分析《永夜星河》后,以为要浅尝剧荒,一部《九重紫》突出重围。 看了宣传片感觉不是很差,看了部分剪辑感觉还可以,看了一两集感…...
《Vue进阶教程》第六课:computed()函数详解(上)
往期内容: 《Vue零基础入门教程》合集(完结) 《Vue进阶教程》第一课:什么是组合式API 《Vue进阶教程》第二课:为什么提出组合式API 《Vue进阶教程》第三课:Vue响应式原理 《Vue进阶教程》第四课&#…...
MFC案例:基于对话框的简易阅读器
一、功能目标: 1.阅读txt文件 2.阅读时可以调整字体及字的大小 3.打开曾经阅读过的文件时,能够自动从上次阅读结束的位置开始显示,也就是能够保存和再次使用阅读信息。 4.对于利用剪贴板粘贴来的文字能够存储成txt文件保存。 5.显示…...
Python+OpenCV系列:图像的运算
文章目录 PythonOpenCV系列:图像的加权和、覆盖1. 图像加权和(加权融合)2. 图像覆盖(区域叠加)3. 应用场景4. 总结 PythonOpenCV系列:图像的加权和、覆盖 在图像处理中,图像的加权和与覆盖是两…...
【Python】【Conda 】Conda vs venv:Python开发者的虚拟环境选择指南
目录 引言一、概述1.1 Conda 虚拟环境1.2 Python venv 虚拟环境 二、安装与设置2.1 安装 Conda 虚拟环境2.2 安装 Python venv 虚拟环境 三、依赖管理3.1 Conda 依赖管理3.2 Python venv 依赖管理 四、适用场景五、性能与资源占用5.1 Conda 性能与资源占用5.2 Python venv 性能…...
gitee仓库的使用
1、本地创建文件夹:比如H:\python-study\Djangogitee 2、在gitee上创建一个仓库,比如django-project 3、Git 全局设置: 在第一步创建的文件夹下,打开Git Bash(需要提前下载好Git工具),执行下面命令 git co…...
openjudge_简单英文题_33:Is It a Tree
题目 33:Is It a Tree 总时间限制: 1000ms 内存限制: 65536kB 描述 Given edges of a graph with N nodes. Check whether it is a tree. 输入 First line: one positive integers N (N < 100). Next N lines: an N*N 0/1 matrix A{a[i][j]}, indicating whether there ex…...
MyBatis-Plus 中 IdWorker.getId() 方法
前言 在分布式系统中,生成全局唯一标识符(ID)是一个常见的需求。MyBatis-Plus 提供了多种 ID 生成策略,其中基于 Twitter 的 Snowflake 算法实现的 IdWorker.getId() 方法因其高效性和适应分布式环境的特点而备受青睐。然而&…...
JAVA面试汇总(三)集合(一)
JAVA多线程七篇终于写完了,今天开始了新的JAVA面试汇总,集合部分,这部分其实比多线程有意思多了,这个计划最多五篇,也许不到五篇,这是第一篇,开卷。 1.Collection和Collections 的区别ÿ…...
zookeeper的安装
zookeeper的安装 一.前言 zookeeper开源组件是为分布式应用,提供协调服务的一种解决方案。本文主要是介绍在Centos7的操作系统中,如何以单机,伪集群,集群的方式来安装部署zookeeper服务。zookeeper要求的jdk版本为1.6以上。本文假…...
2025系统架构师(一考就过):选择题基础知识一
考点1:CPU、指令 真题1:CPU 执行算术运算或逻辑运算时,常将源操作数和结果暂存在(累加器(AC))中。 真题2:在程序的执行过程中,Cache与主存的地址映射是由(硬…...
线性dp—acwing
题目:数字三角形 898. 数字三角形 - AcWing题库 看某个点,是从那些路径过来的去分析 分析1: 代码1:(顺序正推,二维dp数组) #include<bits/stdc.h> using namespace std;const int N 5…...
【QT】:QT(介绍、下载安装、认识 QT Creator)
背景 🚀 在我们的互联网中的核心岗位主要有以下几种 开发(程序员)测试运维(管理机器)产品经理(非技术岗位,提出需求) 而我们这里主要关注的是开发方向,开发岗位又分很…...
GPIO在ZYNQ7000中的结构和相关寄存器解析
GPIO MASK DATA LSW和 MASK DATA MSW LSW和MSW分别是LSW (Least Significant Word)和MSW (Most Significant Word)。 因为DATA是u32,所以如果寄存器的基址是XGPIOPS_DATA_LSW_OFFSET,那么32位就能同时让高16位的MASK DATA MSW]31:16和 MASK DATA LSW的bit7同时为…...
Docker学习笔记
目录 1,Docker概述 I,虚拟机技术 虚拟机技术缺点 II,容器化技术 III,比较docker和虚拟机技术不同 Ⅳ,DevOps(开发,运维) 1,应用更快速的交付和部署 2,更编辑的升级和扩缩容 …...
皮带,传送带异物检测识别数据集,2345张图像,yolo,coco,voc标记三种格式的数据集整理
皮带,传送带异物检测识别数据集,2345张图像,yolo,coco,voc标记三种格式的数据集整理 数据集分割 训练组79% 1860图片 有效集14% 318图片 测试集7% 167图片 预处理 自动定向: 已应用 调…...
大模型qiming面试内容整理-技术能力评估
技术能力评估是大模型相关岗位面试中最重要的环节之一,主要考察候选人是否具备处理复杂机器学习问题、设计和优化模型的能力。以下是技术能力评估的具体内容和可能涉及的题目: 机器学习基础 ● 监督学习与无监督学习: ○ 理解基本的机器学习类型和模型:监督学习:如回归(线…...
前端成长之路:HTML(3)
在HTML中,有列表标签。列表最大的特点是整齐、简洁、有序,用列表进行布局会更加自由方便。根据使用的情景不同,可以将列表分为三大类:无序列表、有序列表和自定义列表。 无序列表 在HTML中使用<ul>标签定义一个无序列表&a…...
小程序给元素设置line-height为0引起页面更新无效
问题 在小程序中使用setData更新,数据更新完毕,页面却没有更新值,甚至出现渲染错乱现象; 发现 但当点击相应事件的时候,视图又更新了。 思考 开始认为是没有在dom渲染后进行数据更新产生的问题,换了方法执行…...
【1355个俚语完结】跟李笑来学美式俚语(Most Common American Idioms): Part 68
Goal Completed 2024年12月11日22点25分完成这本书的学习。习得1355个俚语,尽管有些记得不牢,但是好在走在路上,一直往前走。后面就是多重复,多练习。 查看自己commit的日志,是从2024年11月15日开始学习这本书&#…...
TcpServer 服务器优化之后,加了多线程,对心跳包进行优化
TcpServer 服务器优化之后,加了多线程,对心跳包进行优化 TcpServer.h #ifndef TCPSERVER_H #define TCPSERVER_H#include <iostream> #include <winsock2.h> #include <ws2tcpip.h> #include <vector> #include <map> #…...
螺丝螺帽缺陷检测识别数据集,支持yolo,coco,voc三种格式的标记,一共3081张图片
螺丝螺帽缺陷检测识别数据集,支持yolo,coco,voc三种格式的标记,一共3081张图片 3081总图像数 数据集分割 训练组90% 2781图片 有效集7% 220图片 测试集3% 80图片 预处理…...
若依微服务中配置 MySQL + DM 多数据源
文章目录 1、导入 MySQL 和达梦(DM)依赖2、在 application-druid.yml 中配置达梦(DM)数据源3、在 DruidConfig 类中配置多数据源信息4、在 Service 层或方法级别切换数据源4.1 在 Service 类上切换到从库数据源4.2 在方法级别切换…...
Apache APISIX快速入门
本文将介绍Apache APISIX,这是一个开源API网关,可以处理速率限制选项,并且可以轻松地完全控制外部流量对内部后端API服务的访问。我们将看看是什么使它从其他网关服务中脱颖而出。我们还将详细讨论如何开始使用Apache APISIX网关。 在深入讨…...
【C++】继承
目录 1. 继承的概念及定义 1.1 继承的概念 1.2 继承定义 1.2.1 定义格式 1.2.2 继承基类成员访问方式的变化 1.3 继承类模板 2. 基类和派生类间的转换 3. 继承中的作用域 3.1 隐藏规则: 3.2 考察继承作用域相关选择题 3.2.1 A和B类中的两个func构成什么关…...
设计模式详解(十):策略模式——Strategy
什么是Strategy设计模式? Strategy模式是一种行为型设计模式,它定义了一系列算法,将每种算法封装到独立的类中,使它们可以互换。使用该模式,可以在不修改客户端代码的情况下动态地改变算法的行为。 为什么需要Strate…...
B4X编程语言:B4X控件方法汇总
1、AddNode、AddView方法 AddNode(Node As javafx.scence.Node,Left As Double,Top As Double,Width As Double,Height As Double) B4J控件 AddView(View As javafx.scence.Node,Left As Double,Top As Double,Width As Double,Height As Double) B4J的B4XView …...
如何阅读一本书
阅读很重要,我们真的会阅读吗? 这本书的初版是 1940年,时隔 80年,其内容仍然不过时。第一次读这本书时,给我最大的影响就是主题阅读,每次学习一个新理论、技术,都入手多本关于这项理论、技术的书籍,不同的作者,不同作者的写作背景、角度、目的,导致了风格不同的书籍,…...