Android 11 适配——整理总结篇

news2024/11/28 6:29:08

背景

>  经过检测,我们识别到您的应用,目前未适配安卓11(API30),请您关注适配截止时间,尽快开展适配工作,避免影响应用正常发布和经营。 
> targetSdkVersion30 升级适配工作参考文档:(小米开放平台)[TargetSdk
> 30上架适配指南](https://dev.mi.com/distribute/doc/details?pId=1737) 
> 截至日期为2023124日,请问您可以如期适配嘛?

适配内容

主要处理内容

  • 请求运行时权限
  • 存储机制更新(强制执行分区存储)
    其他
    隐私设置
    1.1强制执行分区存储
    1.2闲置应用权限自动重置
    1.3后台位置访问
    1.4应用包可见性 二、安全
    2.1堆指针标记
    2.2消息框的更新 网络连接
    3.1限制对APN数据库的读取访问 、无障碍服务
    4.1在清单文件中声明与TTS引擎
    4.2在元数据文件中声明"无障碍"… 五、相机
    5.1媒体intent操作需要系统默认 应用打包和安装
    6.1压缩的资源文件
    6.2现在需要APK签名方案v2 ……
    十、非SDK接口限制
    十一、Google Android 11适配信息…

升级版本

直接从26改到30。
在这里插入图片描述

请求运行时权限

权限申请可以遵循官方的最佳做法实践指导

  • 需要注意的点:闲置应用权限自动重置
  • 背景:如果应用以 Android 11 或更高版本为目标平台并且数月未使用,系统会通过自动重置用户已授予应用的运行时敏感权限来保护用户数据。
    此操作与用户在系统设置中查看权限并将应用的访问权限级别更改为拒绝的做法效果一样。
  • 兼容性影响:如果您的应用以Android 11为目标平台,若用户长时间不使用,当用户再次使用时,若应用没有权限校验逻辑则会导致与回收权限相关的业务失效。
  • 第二个注意的点:权限对话框的可见性
    从 Android 11 开始,在应用安装到设备上后,如果用户在使用过程中多次针对某项特定的权限点按拒绝,那么在您的应用再次请求该权限时,用户将不会看到系统权限对话框。
  • 该操作表示用户希望“不再询问”。在之前的版本中,除非用户先前已选中“不再询问”对话框或选项,否则每当您的应用请求权限时,用户都会看到系统权限对话框。
  • Android 11 中的这一行为变更旨在避免重复请求用户已选择拒绝的权限。

权限优化

  • 补充项目中各处具体业务权限遗漏申请的地方。
  • 将一些会提前申请权限的操作后置,在真正使用的地方再按需调用
  • 补充了权限使用说明弹窗授权提示弹窗
  • 将项目中多个权限申请方式统一,改成用XPermission。

原先项目中权限库的不足

  • 无法监控权限是否曾经被禁止过。
    • 因为:它是基于新增一个Activity,然后这个Activity拦截了申请回调,并将回调很局限的区分成拒绝和通过。它所现有的暴露的api无法满足当前的需求。
  • 这个库比较旧,没有继续更新,后续Android版本适配的高版本容易存在风险。

新库的选择

  • 它本身一直在稳定地更新。
  • 它更轻量。
  • 它能满足旧库所不能满足的。
  • 它能够将权限从说明到跳转设置到成功失败等一系列操作全部考虑到并链式配置。
fun requestPermission(context: FragmentActivity, sureBlock: ()->Unit,  permissions: List<String>){
		PermissionX.init(context).permissions(permissions)
			.onForwardToSettings { scope, deniedList ->
				scope.showForwardToSettingsDialog(PermissionToSettings(context, deniedList))
			}
			.request { allGranted, _, _ ->
				if (allGranted) {
					sureBlock.invoke()
				}
			}
	}

关于新库的版本问题

implementation 'com.guolindev.permissionx:permissionx:1.5.0'

直接执行新库,会报错

:app:checkPpDebugAarMetadata 7 errors
1 sec, 436 ms
org.gradle.workers.internal.DefaultWorkerExecutor$WorkExecutionException: occurred while executing com.android.build.gradle.internal.tasks.CheckDuplable
java.lang.RuntimeException: Duplicate class androidx.lifecycle.ViewModelLamodules jetified-lifecycle-viewmodel-ktx-2.3.1-runtime (androidx.lifecycleodel-ktx:2.3.1) and lifecycle-viewmodel-2.5.0-runtime (androidx.lifecycle:
org.gradle.apii.internal.tasks.execution.ExecuteActionsTaskExecuter$MultipFailures: Multiple task action failures occurred:
java.lang.RuntimeException: The minCompileSdk (32) specified in a
java.lang.RuntimeException: The minCompileSdk (31) specified in a
java.lang.RuntimeException: The minCompileSdk (32) specified in a
java lang RuntimeException: The minCompileSdk (31) specified in a

分析原因是项目所适配的最低版本和sdk的不适配。
因此,不能直接用1.7.1;改用了1.5.0.

后续等项目适配到Android13之后,可将新库的版本更新到最新即可。

存储机制更新

1.1 强制执行分区存储
背景

为了让用户更好地管理自己的文件并减少混乱,以 Android 10(API 级别
29)及更高版本为目标平台的应用在默认情况下被授予了对外部存储空间的分区访问权限(即分区存储)。此类应用只能访问外部存储空间上的应用专属目录,以及本应用所创建的特定类型的媒体文件。

在 Android 11 上运行但以 Android 10(API 级别 29)为目标平台的应用仍可请求
requestLegacyExternalStorage
属性。应用可以利用此标记暂时停用与分区存储相关的变更,例如授予对不同目录和不同类型的媒体文件的访问权限。当您将应用更新为以 Android
11 为目标平台后,系统会忽略 requestLegacyExternalStorage 标记。

兼容影响

当您将应用更新为以 Android 11 为目标平台后,您将无法使用requestLegacyExternalStorage,而且也没有其他标记可以提供停用分区存储。

分区存储对于App访问存储方式、App数据存放以及App间数据共享,都产生很大影响。

而Environment.getExternalStorageDirectory() 在 API Level 29 开始已被弃用,开发者应迁移至 Context#getExternalFilesDir(String), MediaStore, 或Intent#ACTION_OPEN_DOCUMENT。

适配建议

如果您将应用专属文件存储在外部存储空间中,则可以将这些文件存放在外部存储空间中的应用专属目录内,以便更加轻松地采用分区存储。这样,在启用分区存储后,您的应用将可以继续访问这些文件。

如需让您的应用适合分区存储,请参阅存储用例和最佳实践指南。

具体适配参考:

  • https://developer.android.google.cn/training/data-storage#scoped-storage
  • https://developer.android.google.cn/preview/privacy/storage
  • https://developer.android.google.cn/training/data-storage/use-cases?hl=zh-cn

----------------------------------------------------------------------------------------------------.

需要重点适配的内容:

  • 檢查使用到的第三方库是否存在适配上的问题。(比如PictureSelector、Matisse、ShareSDK等第三方库就需要做适配处理)
  • 鸿蒙系统的测试机在浏览相册功能有偶现异常现象
  • 处理下载的图片视频资源同步更新到系统相册。
  • 拍照、图片上传和压缩缓存处理。
  • 验证了不同系统的测试机(Android 9、10、11、13。HarmonyOS 3.00。)

关键步骤
涉及到文件储存的功能。
通过官方推荐的方式来替换掉关键代码:

Environment.getExternalStorageDirectory()

如果直接使用以上代码进行存储的话,会报一下错误。

FileNotFoundException xxxxxxxxxx open failed: EPERM (Operation not permitted)

可以使用

context.getExternalFilesDir(null)?.absolutePath)

来存储,目录为:/storage/emulated/0/Android/data/com.xxx/files


关于鸿蒙系统比较特殊的点

resizeBmp = BitmapFactory.decodeFile(file.getPath(), opts);

场景:当通过相册拿到外部文件路径之后,使用以上代码获取bitmap,会偶现失败。检查权限相关无异常,但是会偶尔报这个错误

Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/com.xxx/1699410185196.jpg: open failed: EACCES (Permission denied)

通过调试和看日志,没能找到相关获取bitmap失败的其他日志。根据以上的这条error日志,判断是否鸿蒙系统对这块的适配有问题。因此,在华为的包中,添加一下代码:

<manifest ... >
  <application android:requestLegacyExternalStorage="true" ...>
    ...
  </application>
</manifest>

虽然在官方文档中,表示:

当您将应用更新为以 Android 11
为目标平台后,您将无法使用requestLegacyExternalStorage,而且也没有其他标记可以提供停用分区存储。

但是,通过这种方式进行设置,确实能避免鸿蒙系统会存在偶现失败的场景发生。


Permission to access file: /storage/emulated/0/Mob/comm/locks/.dhlock is denied uid = 10242
  java.lang.SecurityException: com.yishouapp.fumi has no access to content://media/external_primary/file/1000000118
      at com.android.providers.media.MediaProvider.enforceCallingPermissionInternal(MediaProvider.java:10152)
      at com.android.providers.media.MediaProvider.enforceCallingPermission(MediaProvider.java:10049)
      at com.android.providers.media.MediaProvider.checkAccess(MediaProvider.java:10177)
      at com.android.providers.media.MediaProvider.checkIfFileOpenIsPermitted(MediaProvider.java:9068)

项目中一些第三方库的调整:

图片选择器PictureSelector

报错日志:

Unable to decode stream: java.io.FileNotFoundException:
/storage/emulated/0/DCIM/com.xxx/1699410185196.jpg: open
failed: EACCES (Permission denied)

  • 检查权限申请代码等细节,一切正常。
    这个库需要更新到高版本才能适配
 'com.github.LuckSiege.PictureSelector:picture_library:v2.6.0'

因为项目中用到了camera-view这个库。因此,这个库的相关代码调用,也需要做代码上的适配,会有一些api上的改动。

知乎图片选择器Matisse

参考:
报错日志:

com.android.providers.media.module Permission to access file:
/storage/emulated/0/Mob/comm/lockss/.dhlock is denied uid = 10242
java.lang.SecurityException: com.yishouapp.fumi has no access to
conttent://media/external_primary/file/100000000000118 at
com.android.providers.media.MediaProvider.enforceCallingPermissiionInternal(MediaProvider.java:10152)
at
com.android.providers.media.MediaProvider.enforceCallingPermission(MediaProvider.java:10049)
at
com.android.providers.media.MediaProvider.checkAccess(MediaProvider.java:10177)
at com.android.
roviders.media.MediaProvider.checkIfFileOpenIsPermitted(MediaProvider.java:9068)
at
com.android.providers.media.MediaProvider.onFileOpenForFusse(MediaProvider.java:9181)
FATAL EXCEPTION: ModernAsyncTask #1 com.yishouapp.fumi Process:
com.yishouapp.fumi, PID:30137 java.lang.RuntimeException: An error
occurred while executing doInBackground( at
androidx.loader.content.ModernAsyncTask 3. d o n e ( M o d e r n A s y n c T a s k . j a v a : 164 ) C a u s e d b y : j a v a . l a n g . I l l e g a l A r g u m e n t E x c e p t i o n : I n v a l i d c o l u m n C O U N T ( ∗ ) A S c o u n t < 6 i n t e r n a l l i n e s > a t a n d r o i d . d a t a b a s e . D a t a b a s e U t i l s . r e a d E x c e p t i o n F r o m P a r c e l ( D a t a b a s e u t i l s . j a v a : 172 ) a t a n d r o i d . d a t a b a s e . D a t a b a s e U t i l s . r e a d E x c e p t i o n F r o m P a r c e l ( D a t a b a s e u t i l s . j a v a : 142 a t a n d r o i d . c o n t e n t . C o n t e n t P r o v i d e r P r o x y . q u e r y ( C o n t e n t P r o v i d e r N a t i v e j a v a : 481 ) a t a n d r o i d . c o n t e n t . C o n t e n t R e s o l v e r . q u e r y ( C o n t e n t R e s o l v e r . j a v a : 1221 a t a n d r o i d . c o n t e n t . C o n t e n t R e s o l v e r . q u e r y ( C o n t e n t R e s o l v e r . j a v a : 1152 a t a n d r o i d x . c o r e . c o n t e n t . C o n t e n t R e s o l v e r C o m p a t . q u e r y ( C o n t e n t R e s o l v e r C o m p a . j a v a : 81 a t a n d r o i d x . l o a d e r . c o n t e n t . C u r s o r L o a d e r . l o a d I n B a c k g r o u n d ( C u r s o r L o a d e r . j a v a : 63 ) a t c o m . z h i h u . m a t i s s e . i n t e r n a l . l o a d e r . A l b u m L o a d e r . l o a d I n B a c k g r r o u n d ( A l b u m L o a d e r . j a v a : 98 a t c o m . z h i h u . m a t i s s e . i n t e r n a l . l o a d e r . A l b u m L o a d e r . l o a d I i n B a c k g r o u n d ( A l b u m L o a d e r . j a v a : 34 ) a t a n d r o i d x . l o a d e r . c o n t e n t . A s y n c T a s k L o a d e r . o n L o a d I n B a c k g r o u n d ( A s y n c T a s k L o a d e r . j a v a : 307 ) a t a n d r o i d x . l o a d e r . c o n t e n t . A s y n c T a s k L o a d e r 3.done(ModernAsyncTask.java:164) Caused by: java.lang.IllegalArgumentException: Invalid column COUNT(*) AS count <6 internal lines> at android.database.DatabaseUtils.readExceptionFromParcel(Databaseutils.java:172) at android.database.DatabaseUtils.readExceptionFromParcel(Databaseutils. java:142 at android.content.ContentProviderProxy.query (ContentProviderNativejava:481) at android.content.ContentResolver.query(ContentResolver.java:1221 at android.content.ContentResolver.query(ContentResolver.java:1152 at androidx.core.content.ContentResolverCompat.query (ContentResolverCompa.java:81 at androidx.loader.content.CursorLoader.loadInBackground(CursorLoader.java:63) at com.zhihu.matisse.internal.loader.AlbumLoader.loadInBackgrround(AlbumLoader.java:98 at com.zhihu.matisse.internal.loader.AlbumLoader.loadIinBackground(AlbumLoader.java:34) at androidx.loader.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:307) at androidx.loader.content.AsyncTaskLoader 3.done(ModernAsyncTask.java:164)Causedby:java.lang.IllegalArgumentException:InvalidcolumnCOUNT()AScount<6internallines>atandroid.database.DatabaseUtils.readExceptionFromParcel(Databaseutils.java:172)atandroid.database.DatabaseUtils.readExceptionFromParcel(Databaseutils.java:142atandroid.content.ContentProviderProxy.query(ContentProviderNativejava:481)atandroid.content.ContentResolver.query(ContentResolver.java:1221atandroid.content.ContentResolver.query(ContentResolver.java:1152atandroidx.core.content.ContentResolverCompat.query(ContentResolverCompa.java:81atandroidx.loader.content.CursorLoader.loadInBackground(CursorLoader.java:63)atcom.zhihu.matisse.internal.loader.AlbumLoader.loadInBackgrround(AlbumLoader.java:98atcom.zhihu.matisse.internal.loader.AlbumLoader.loadIinBackground(AlbumLoader.java:34)atandroidx.loader.content.AsyncTaskLoader.onLoadInBackground(AsyncTaskLoader.java:307)atandroidx.loader.content.AsyncTaskLoaderLoadTask.doInBackground(AsyncTaskLoader.java:60
at
androidx.loader.content.AsyncTaskLoader$LoadTask.doInBackground(AsyncTaskLoader.java:48
at
androidx.loader.content.ModernAsyncTask$2.call(ModernAsyndTask.java:141)
<4 internal lines

该库已经从19年开始就不再维护了。因此,本次调整,将替换掉这个库。

微信分享问题排查

  • ShareSDK使用权限情况 ShareSDK使用权限情况
  • 弃用这个库,改用自己写。
  • 具体参考:分享与收藏-Android开发手册
  • 特殊需求,上面官方的开发手册中,很详细地讲解了各种分享方式和场景,但是并不支持分享队长图片到微信中来。因为业务需求需要,需要实现分享多张图片,因此通过下面这种Intent跳转携带Extra的方式来实现。
/分享的图片集合
val imageUris = ArrayList<Uri>()
bitmaps.forEach {
	imageUris.add(SaveUtils.saveBitmapToAlbumForShare(activity, it))
}

//分享到微信好友
activity.startActivity(
	Intent().apply {
		component = ComponentName("com.tencent.mm", "com.tencent.mm.ui.tools.ShareImgUI")
		action = Intent.ACTION_SEND_MULTIPLE
		type = "image/*"
		putExtra(Intent.EXTRA_STREAM, imageUris)
})

升级腾讯云orcsdk

  • 需要更新库的升级,并且需要添加混淆。
    在这里插入图片描述
    api调用方面,也需要做同步更改:
// 启动 ocr 识别,识别类型为身份证正面
OcrSDKKit.getInstance().startProcessOcr(MainActivity.this, OcrType.IDCardOCR_FRONT, customConfigUi, new ISDKKitResultListener() {
    @Override
    public void onProcessSucceed(String response, String srcBase64Image, String requestId) {
        popTip(response, "Succeed"); // 展示 ocr 识别结果
    }

    @Override
    public void onProcessFailed(String errorCode, String message, String requestId) {
        popTip(message, errorCode); // 展示 ocr 识别错误信息
    }
});

总结:存储这块,很多项目中使用到的第三方库都没有做很好兼容。需要去仔细排查然后去做适配或者废弃替换工作。整体还是存在风险的,因此不会全量覆盖所有渠道,逐步覆盖了。

文件路径统一整理

  • 兼容高低版本,统一处理保存主路径。
  • 整理统一图片、视频、文件、h5缓存下载保存等路径。

关于共享

注意一个点,如果要处理保存图片/视频,并同步到相册的话。则不能直接将文件资源存储在私有目录中,私有目录的文件无法共享到相册中。可以通过MediaStore来操纵,具体可以看文档:
访问共享存储空间中的媒体文件

心得总结

  • 本次适配,涉及了整体app的权限申请优化,识别、分享、相册、存储方案的统一调整,以及第三方库版本依赖相关的内容。改动代码量比较大,涉及到的业务页面也较多,还发现了一些隐藏至今的历史遗留bug。
  • 项目比较久了,经历的人手多了,避免不了存在一些脏代码。重构代码不仅在做技术优化需求中进行,平时的迭代甚至改bug的过程中,也可以及时执行。所以说,平时代码的review是必不可少的,这样可以规范很多。
  • 另外,一些能统一封装的代码也需要规整,像项目中有三种权限方式,两个权限申请第三方库这种,还是需要避免的,最好统一入口封装,如果避免不了需要使用不同方案处理,建议使用策略模式来设计,而当一个功能的实现涉及到需要相册、存储、识别、分享等多个方案的话,也可以采用外观模式来进行设计,代码设计规范,后续改动、迭代、优化都会事半功倍。
  • 而且保存文件的入口和工具类也比较杂,随处放一点,需要整改的时候,排查起来也比较费劲并且容易遗漏。再一个是第三方库版本需要统一,避免不同module引入统一个库不同版本的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1300406.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

redis数据淘汰策略:

面试官&#xff1a;了解redis数据淘汰策略吗&#xff1f; 就是当Redis内存使用达到设置的上限时&#xff0c; 此时需要使用redis数据淘汰机制来进行数据淘汰。&#xff08;有针对key的 和 针对value数据的&#xff09; Redis支持8种不同策略来选择要删除的key&#xff1a; n…

ant Design of vue 实现table每栏动态根据条件设置背景颜色(table栏每一栏颜色自定义)

效果图&#xff1a; 注意效果图中&#xff0c;table的表格每一栏颜色都要不一样 代码实现&#xff1a; 页面结构&#xff1a; <a-table :columns"columns" :loading"tableLoading" :data-source"tableData" rowKeyid size"middle&quo…

IntelliJ IDEA开启git版本控制的简单教程

这篇文章想要分享一下怎么在IntelliJ IDEA开启版本控制&#xff0c;博主使用的是gitee&#xff0c;首先需要安装git&#xff0c;关于git的安装这里就不介绍了&#xff0c;很简单。 目录 创建git仓库 创建项目 开启版本控制 拉取项目 创建git仓库 首先&#xff0c;需要登录…

C++ 模拟实现vector

目录 一、定义 二、模拟实现 1、无参初始化 2、size&capacity 3、reserve 4、push_back 5、迭代器 6、empty 7、pop_back 8、operator[ ] 9、resize 10、insert 迭代器失效问题 11、erase 12、带参初始化 13、迭代器初始化 14、析构函数 完整版代码 一、…

Python 调用 Halcon 模板匹配实现目标定位

一、Halcon 当谈及计算机视觉领域中强大的工具和框架时&#xff0c;Halcon&#xff08;由德国MVTec 公司开发&#xff09;无疑是一个备受关注的系统。Halcon被广泛用于工业视觉和机器视觉应用中&#xff0c;其强大的功能和灵活性使其成为许多开发人员和研究人员的首选选择。 …

【合集】SpringBoot——Spring,SpringBoot,SpringCloud相关的博客文章合集

前言 本篇博客是spring相关的博客文章合集&#xff0c;内容涵盖Spring&#xff0c;SpringBoot&#xff0c;SpringCloud相关的知识&#xff0c;包括了基础的内容&#xff0c;比如核心容器&#xff0c;springMVC&#xff0c;Data Access&#xff1b;也包括Spring进阶的相关知识&…

支持大模型训练的计算机系统

摘要&#xff1a; 训练数据决定了基础大模型可用的理论信息&#xff0c;模型架构和训练目标决定了可以提取多少信息&#xff0c;计算机系统决定了实际可实现的内容。在数据和模型大小方面&#xff0c;系统是扩展的关键瓶颈&#xff0c;这两者似乎都可以可靠地跟踪能力的改进。在…

Bypass open_basedir

讲解 open_basedir是php.ini中的一个配置选项&#xff0c;可用于将用户访问文件的活动范围限制在指定的区域。 假设open_basedir/var/www/html/web1/:/tmp/&#xff0c;那么通过web1访问服务器的用户就无法获取服务器上除了/var/www/html/web1/和/tmp/这两个目录以外的文件。…

【网络安全】vulhub靶场搭建与一个漏洞的简单示例

vulhub是一个经典的靶场&#xff0c;里面大约包含了200个不同的漏洞&#xff0c;可以说是安全从业者必刷。 无需docker知识&#xff0c;简单执行一条命令即可编译、运行一个完整的漏洞靶场镜像。 我的环境是CentOS 7。 先安装docker sudo curl -L "https://github.com…

Linux-帮助命令的使用和练习(type、man、help、info详解)

目录 5.3.1 type-判断是否为内部命令 5.3.2 man-查看详细文档 5.3.3 help-查看shell内部命令的帮助信息 5.3.4 --help-查看系统外部命令帮助信息 5.3.5 info-查看info格式的帮助指令 5.3.6 /usr/share/doc-存储软件包的文档信息 平时我们看到的命令大多数都可以查看帮助文…

Redis有序集合对象

一.编码 有序集合的编码可以是ziplist或者skiplist。 ziplist编码的有序集合对象使用压缩列表作为底层实现&#xff0c;每一个集合元素使用紧挨在一起的两个压缩列表节点来保存。第一个节点保存元素的成员(member)&#xff0c;而第二个元素则保存元素的分值(score)。 127.0.0.…

全面解析“由于找不到hid.dll,无法继续执行代码”的4个解决方法

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中之一就是“找不到hid.dll”。这个问题通常出现在尝试运行某个程序或访问某个设备时。那么&#xff0c;当我们遇到这个问题时&#xff0c;应该如何解决呢&#xff1f;本文将详细介绍找不到hid.dll的解…

Java第二十一章总结

网络编程三要素 ip地址&#xff1a;计算机在网络中的唯一标识 端口&#xff1a;应用程序在计算机中唯一标识 协议&#xff1a;通信协议&#xff0c;常见有UDP和TCP协议 InetAddress类 表示Internet协议地址 //返回InetAddress对象 InetAddress byName InetAddress.…

程序员的养生之道

程序员的养生之道 1 对程序员的初次印象2 我的养生之道2.1 规律作息&#xff1a;2.2 合理饮食&#xff1a;2.3 健康饮食&#xff1a;2. 4 增强锻炼&#xff1a;2. 5 心态平和&#xff1a;2. 6 生活习惯&#xff1a;2.7 定期体检&#xff1a;2.8 特殊注意&#xff1a;2.9 补充能…

Zookeeper系统性学习-应用场景以及单机、集群安装

Zookeeper 是什么&#xff1f; Zookeeper 为分布式应用提供高效且可靠的分布式协调服务&#xff0c;提供了诸如统一命名服务、配置管理和分布式锁等分布式的基础服务。在解决分布式数据一致性方面&#xff0c;ZooKeeper 并没有直接采用 Paxos 算法&#xff0c;而是采用了名为 …

微表情检测(三)----基于光流特征的微表情检测

Micro-expression spotting based on optical flow features 基于光流特征的微表情检测 Abstract 本文提出了一种高精度和可解释性的自动微表情检测方法。首先&#xff0c;我们设计了基于鼻尖位置的图像对齐方法&#xff0c;以消除由头部晃动引起的全局位移。其次&#xff0…

C# Winform 日志系统

目录 一、效果 1.刷新日志效果 2.单独日志的分类 3.保存日志的样式 二、概述 三、日志系统API 1.字段 Debug.IsScrolling Debug.Version Debug.LogMaxLen Debug.LogTitle Debug.IsConsoleShowLog 2.方法 Debug.Log(string) Debug.Log(string, params object[]) …

lv12 系统移植导学 1

1 导学 Kernel学习主要包括三块内容&#xff0c;ARM&#xff08;汇编、协议&#xff09;、系统移植、驱动移植 lv12主要时安装系统linux linux主要帮我们实现了5大功能 1 进程、线程管理 2 内存管理 3 网络协议栈管理 4 文件系统管理 5 设备管理 2 移植的目的 不同架构…

ptmalloc:从内存虚拟化说起

前言 本文并不局限于ptmalloc的原理&#xff0c;而是从linux的内存虚拟化和系统调用原理出发&#xff0c;结合各种语言实现&#xff0c;讲明内存分配方面的trade off&#xff0c;力图事无巨细&#xff0c;追根究底。本文内容包括但不限于&#xff1a;NIO原理、0拷贝原理、内存…

AirServer 5.63中文破解2024最新图文安装激活教程含许可证

AirServer是一款便捷式投屏软件&#xff0c;它的主要功能在于实时地将移动设备上的图像画面内容投放到电脑设备上&#xff0c;让电脑成为iPad、iPhone等iOS系统设备的大屏显示器。 在设备之间建立局域网内的信号发送与接收通道&#xff0c;确保数据可以稳定安全地进行传输。下面…