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

做网站去哪个公司镇江网站优化推广

做网站去哪个公司,镇江网站优化推广,国家建设标准网站,网站注册界面代码前几天刚聊过 《Google 开始正式强制 Android 适配 16 K Page Size》 之后,被问到最多的问题是「怎么查看项目是否支持 16K Page Size」 ?其实有很多直接的方式,但是最难的是当你的项目有很多依赖时,怎么知道这个「不支持的动态库…

前几天刚聊过 《Google 开始正式强制 Android 适配 16 K Page Size》 之后,被问到最多的问题是「怎么查看项目是否支持 16K Page Size」 ?其实有很多直接的方式,但是最难的是当你的项目有很多依赖时,怎么知道这个「不支持的动态库 so」 文件是哪个依赖?有不少人的项目里可能有几十个 so ,如果一个一个那场景可太"有爱"了。

后面的脚本提供查找思路。

首先第一种方法用官方的脚本,保存下方脚本为 shell.sh ,然后执行 ./shell.sh src/main/jinLibs ,就可以检测到目录下所有动态库是否支持 16K:

#!/bin/bash# usage: alignment.sh path to search for *.so filesdir="$1"RED="\e[31m"
GREEN="\e[32m"
ENDCOLOR="\e[0m"matches="$(find $dir -name "*.so" -type f)"
IFS=$'\n'
for match in $matches; dores="$(objdump -p ${match} | grep LOAD | awk '{ print $NF }' | head -1)"if [[ $res =~ "2**14" ]] || [[ $res =~ "2**16" ]]; thenecho -e "${match}: ${GREEN}ALIGNED${ENDCOLOR} ($res)"elseecho -e "${match}: ${RED}UNALIGNED${ENDCOLOR} ($res)"fi
done

整个 Apk 的话,可以直接解压 Apk ,然后对动态库的目录用脚本扫描。

第二种方法就是通过 Google Play 的 app bundle 资源管理器页面直接查看,如果有问题,会看到类似的情况:

另外,如果 so 没问题,但是还是提示你不支持 16 KB,那么很可能是你需要升级 AGP ,建议至少升级到 AGP 8+ ,最优是升级到 8.5.1 之后:

没有问题的情况下是这样:

第三种方法就是下载最新的 libchecker ,如果动态库都有“16 KB” ,那就是正常:

还有一种方法就是使用 readelf 工具,通过终端对比 so 的 elf 对齐情况,工具一般位于 /Users/guoshuyu/Library/Android/sdk/ndk/21.4.7075529/toolchains/aarch64-linux-android-4.9/prebuilt/darwin-x86_64/bin,通过以下命令可以输出对应参数:

./aarch64-linux-android-readelf -l /Users/guoshuyu/workspace/android/******/libs/arm64-v8a/libijkffmpeg.so

如下两种图所示:

  • 图 1 LOAD 段在 Align 栏目显示 1000 (16进制,即 4096) ,也就是还没增加 16K 对齐的状态
  • 图 2 LOAD 段在 Align 栏目显示 4000 (16进制,即 16384) ,是增加 16K 对齐的状态

注意,是 1000 才是 4K,而 10000 是 65536 ,那就是64K 对齐,属于 16K 的 4倍,那「理论上」应该是对齐的

最后,你还可以在 Android Studio 里运行你的 App,然后 Android Studio 会提示存在哪些动态库没适配 16 KB

注意,目前需要 Android Studio Narwhal ,最新版 Canary 10,并且有个 Bug ,需要首次运行之后,关闭 Android Studio ,然后再次打开,再运行,才会弹出提示

最后,如果你发现存在动态库不适配,但是你又不知道这个动态库是哪个 aar 远程依赖的,可以通过下方脚本执行 ./gradlew findSoFileOrigins 来输出:

// 在你的模块级别 build.gradle 文件中添加此任务
// 例如: app/build.gradletask findSoFileOrigins {description = "扫描项目依赖的 AAR 文件,找出 .so 文件的来源。"group = "reporting" // 将任务归类到 "reporting" 组下doLast {// 用于存储 AAR 标识符及其包含的 .so 文件路径// 键 (Key): AAR 的字符串标识符 (例如:"project :gsyVideoPlayer", "com.example.library:core:1.0.0")// 值 (Value): 一个 Set 集合,包含该 AAR 内所有 .so 文件的路径 (字符串)def aarSoFilesMap = [:]def variants = nullif (project.plugins.hasPlugin('com.android.application')) {variants = project.android.applicationVariants} else if (project.plugins.hasPlugin('com.android.library')) {variants = project.android.libraryVariants} else {project.logger.warn("警告: findSoFileOrigins 任务需要 Android 应用插件 (com.android.application) 或库插件 (com.android.library)。")return}if (variants == null || variants.isEmpty()) {project.logger.warn("警告: 未找到任何变体 (variants) 来处理。")return}variants.all { variant ->project.logger.lifecycle("正在扫描变体 '${variant.name}' 中的 AAR 依赖以查找 .so 文件...")// 获取该变体的运行时配置 (runtime configuration)def configuration = variant.getRuntimeConfiguration()try {// 配置一个构件视图 (artifact view) 来精确请求 AAR 类型的构件def resolvedArtifactsView = configuration.incoming.artifactView { view ->view.attributes { attributes ->// 明确指定我们只对 artifactType 为 'aar' 的构件感兴趣// AGP 也常用 "android-aar",如果 "aar" 效果不佳,可以尝试替换attributes.attribute(Attribute.of("artifactType", String.class), "aar")}// lenient(false) 是默认行为。如果设为 true,它会尝试跳过无法解析的构件而不是让整个视图失败。// 但如果像之前那样,是组件级别的变体选择失败 (如 gsyVideoPlayer),lenient 可能也无法解决。// view.lenient(false)}.artifacts // 获取 ResolvedArtifactSetproject.logger.info("对于变体 '${variant.name}',从配置 '${configuration.name}' 解析到 ${resolvedArtifactsView.artifacts.size()} 个 AAR 类型的构件。")resolvedArtifactsView.each { resolvedArtifactResult ->// resolvedArtifactResult 是 ResolvedArtifactResult 类型的对象File aarFile = resolvedArtifactResult.file// 获取组件的标识符,这能告诉我们依赖的来源// 例如:"project :gsyVideoPlayer" 或 "com.google.android.material:material:1.7.0"String aarIdentifier = resolvedArtifactResult.id.componentIdentifier.displayNameaarSoFilesMap.putIfAbsent(aarIdentifier, new HashSet<String>())if (aarFile.exists() && aarFile.name.endsWith('.aar')) {// project.logger.info("正在检查 AAR: ${aarIdentifier} (文件: ${aarFile.name})")try {project.zipTree(aarFile).matching {include '**/*.so' // 匹配 AAR 中的所有 .so 文件}.each { File soFileInZip ->aarSoFilesMap[aarIdentifier].add(soFileInZip.path)}} catch (Exception e) {project.logger.error("错误: 无法检查 AAR 文件 '${aarIdentifier}' (路径: ${aarFile.absolutePath})。原因: ${e.message}")}} else {if (!aarFile.name.endsWith('.aar')) {project.logger.debug("跳过非 AAR 文件 '${aarFile.name}' (来自: ${aarIdentifier}),其构件类型被解析为 AAR。")} else {project.logger.warn("警告: 来自 '${aarIdentifier}' 的 AAR 文件不存在: ${aarFile.absolutePath}")}}}} catch (Exception e) {// 这个 catch 块会捕获解析构件视图时发生的错误// 这可能仍然包括之前遇到的 "Could not resolve all artifacts for configuration" 错误,// 如果问题非常根本,即使是特定的构件视图也无法克服。project.logger.error("错误: 无法为配置 '${configuration.name}' 解析 AAR 类型的构件。" +"可能项目设置中存在依赖变体匹配问题," +"详细信息: ${e.message}", e) // 打印异常堆栈以获取更多信息project.logger.error("建议: 请检查项目依赖(尤其是本地子项目如 ':xxxxx')的构建配置," +"确保它们能正确地发布带有标准 Android 库属性(如组件类别、构建类型,以及适用的 Kotlin 平台类型等)的变体。")// 如果希望任务在此处停止而不是尝试其他变体,可以取消下一行的注释// throw e}}// 打印结果if (aarSoFilesMap.isEmpty()) {project.logger.lifecycle("\n在所有已处理变体的可解析 AAR 依赖中均未找到 .so 文件,或者依赖解析失败。")} else {println "\n--- AAR 依赖中的 .so 文件来源 ---"// 按 AAR 标识符排序以获得一致的输出aarSoFilesMap.sort { it.key }.each { aarId, soFileList ->if (!soFileList.isEmpty()) {println "${aarId}:" // 例如:project :gsyVideoPlayer: 或 com.some.library:core:1.0:soFileList.sort().each { soPath -> // 对 .so 文件路径排序println "  - ${soPath}"     // 例如:  - jni/armeabi-v7a/libexample.so}}}println "----------------------------------"}project.logger.lifecycle("任务执行完毕。要再次运行此任务,请执行: ./gradlew ${project.name}:${name}")}
}

这个脚本我是在 APG 8+ 下测试,不同 AGP 可能存在细微 API 差异,思路上一样。

当然,最终还是要在 16 KB 环境运行没有崩溃才行, 在之前的文章我就分享过,很多 so 查看时虽然分页是 16K 或者 64K ,但是它还是有问题的,跑在 16K 上是会崩溃的,具体原因有 NDK 工具可能过老之类:

当时是 NDK10e 等版本,编译出来的 so 都是两个 LOAD 段的 Align 是 10000(65536) , 也就是 64K 对齐,属于 16K 的 4倍,那「理论上」应该是对齐的,但是跑在 16K 上会 crash ,不过 crash 提示也不是 so 不对齐,而是在某段代码执行时出现 crash,并且你定位到的地址代码会很奇葩。

测试环境可以使用模拟器,一般适配 16 KB 的就是 arm64 ,所以 x86_64 模拟器基本没用,而且需要 Android studio Koala Feature Drop 之后的版本才行:

如果你的 Apk 没适配 16 KB ,那么在 Android 16 的 16 KB 模拟器上会看到这样的提示:

目前在 React Native 和 Flutter 都已经支持了 16 KB:

  • Flutter 至少 3.22 版本
  • RN 至少 0.77 版本

比如你的 RN 版本太老,就是看到类似下面的场景:

最后,如果你还没适配或者了解 16 KB,可以参考一下文章

  • Android 15 上适配 16K Page Size 的填坑思路,以 IJKPlayer 为例子

  • Android 15 之如何快速适配 16K Page Size

  • Android 15 适配之16K Page Size :为什么它会是最坑的一个适配点

http://www.dtcms.com/wzjs/797202.html

相关文章:

  • 网站模板吧网站开发哪种框架
  • 网站图片悬浮代码中国山东建设监理协会官方网站
  • 网站不想让百度收录政务公开 加强门户网站建设
  • 郑州有哪些搞网站开发的公司wordpress免费主题插件下载地址
  • 大数据技术建设网站最新新闻热点素材
  • 如何进入官方网站湛江网站建设方案推广
  • 网站建设方面存在的问题怎么做公司官方网站
  • 网站内套网站代码简述网站建设流程中的各个步骤
  • 为什么建设网站要年年交钱备案期间 网站
  • 做网站服务器用谁的搜索引擎优化seo的英文全称是
  • 公司如何组建网站wordpress纯商城系统
  • 巩义网站建设案例课堂美食网站制作代码
  • Wordpress建站的电商哪个岗位最吃香
  • 建立网站的关键是定位网页开发环境一般写什么
  • 湖北省建设厅官方网站电话阿里云域名注册流程
  • 网站建设托管预算清单Wordpress host
  • 海沧区建设局网站市政处帮忙建网站的人
  • 网站建设名列前茅营销策略研究论文范文
  • 物流网站建设合同范本专业建网站平台
  • 较成功营销网站的例子网站建设需要怎么维护
  • 白云区pc端网站建设广告公司注册需要什么条件
  • 网站数据库怎么配置网站建设与网页设计制作书籍
  • 广州海珠网站建设深圳网站建设
  • 沈阳做网站哪家质量好价格低搜书网站 怎么做
  • 天河微网站建设市场价格查询
  • 北京示范校建设网站百度官网首页网址
  • 舟山建设信息港门户网站宠物网站建设规划书
  • 网站建设推荐书籍酒店网站建设系统介绍
  • 融水苗族自治县网站建设公司网站建立的意义
  • 上海加盟网站建设苏州 中英文网站建设