UE4安卓打aab包时,同时存在“gradle”、“arm64/gradle”两个Gradle工程的原因

两个Gradle工程的现象

在出安卓aab包时,观察到存在以下两个Gradle工程:

1、Intermediate\Android\arm64\gradle (称为arm64的Gradle)

2、Intermediate\Android\gradle(称为根下的Gradle)

 

它们存在一些小的差异。下面是“为何有两个Gradle工程”的结论。

原因



1、假设指定了若干种架构,那么就会有多个子目录。在我们的例子中,仅存在 arm64目录。(以及根部的 gradle目录,这是你所知道的)

2、如果“差异不大”,UE4就会统一采用 gradle目录来打aab,来作为所有架构的aab。我们的例子中,就属于这种情况。代码里叫做“bCombinedBundleOK”,即统一打根部gradle来打出aab。

3、下面情况属于“差异大”:
● arm64目录缺乏它的gradle目录。代码搜“Source directory missing”
● arm64目录/Gradle目录的 “AndroidManifest.xml”在某些属性上存在差异,细节太细不用管。代码搜“AndroidManifest.xml files differ too much”
● arm64目录/Gradle目录的 “gradle.properties”在某些属性上存在差异,细节太细不用管。代码搜“Gradle projects differ too much”
● 有更加多的未知差异。代码搜“Gradle projects differ too much”

4、上面四种情况对应的日志都没搜到,说明 bCombinedBundleOK (差异不大)

结论:最终打出aab时,确实没用上 arm64 架构目录。打包只使用了gradle目录。

代码示意图

 

关键代码与日志

请打开UEDeployAndroid.cs:MakeApk() 方法,针对上图的一些代码,做下面的解释:

1、UnrealBuildTool.UEDeployAndroid.MakeApk()

打aab|apks 或打apk的入口函数。

2、foreach (Tuple<string, string, string> build in BuildList)

在我的项目案例中,只有 arm64 。接下来的若干代码要点,处在该循环中,实际上只跑了一次(即arm64)。

3、(在循环中)

                string UE4BuildPath = Path.Combine(IntermediateAndroidPath, Arch.Substring(1).Replace("-", "_"));
                // 这个值是:{项目}\Intermediate\Android\arm64

4、(在循环中)

// check to see if libUE4.so needs to be copied
if (BuildListComboTotal > 1 || FilesAreDifferent(SourceSOName, FinalSOName))
{ // 没有执行Log.TraceInformation("\nCopying new .so {0} file to jni folder...", SourceSOName);Directory.CreateDirectory(JniDir);// copy the binary to the standard .so locationFile.Copy(SourceSOName, FinalSOName, true);Log.TraceWarning("// *Gradle* SourceSOName {0} copy to ->>  FinalSOName {1}", SourceSOName, FinalSOName);//  SourceSOName D:\项目\Binaries\Android\项目-Android-Test-arm64.so 拷贝给:// D:\项目\Intermediate\Android\arm64\jni\arm64-v8a\libUE4.so ✔// 案例中,没有拷贝,被增量跳过了。File.SetLastWriteTimeUtc(FinalSOName, File.GetLastWriteTimeUtc(SourceSOName));
}// remove any read only flags
FileInfo DestFileInfo = new FileInfo(FinalSOName);
DestFileInfo.Attributes = DestFileInfo.Attributes & ~FileAttributes.ReadOnly;
File.SetLastWriteTimeUtc(FinalSOName, File.GetLastWriteTimeUtc(SourceSOName));Log.TraceWarning("// *Gradle* SourceSOName {0} DestApkName {1}, FinalSOName {2}", SourceSOName, DestApkName, FinalSOName);
// 实际是:2024-10-28 21:17:08:726 : WARNING:
// // *Gradle* SourceSOName D:\项目\Binaries\Android\项目-Android-Test-arm64.so
// DestApkName D:\项目\Binaries\Android\项目-Android-Test-arm64.apk,
// FinalSOName D:\项目/Intermediate\Android\arm64/jni/arm64-v8a/libUE4.so

拷贝libUE4.so,这是一个重要的符号表文件。

5、 (在循环中)

                File.Copy(Path.Combine(UE4BuildPath, "AndroidManifest.xml"), GradleManifest, true);
                // 应该是指: 项目\Intermediate\Android\arm64/AndroidManifest.xml 拷贝给  项目\Intermediate\Android\arm64\gradle\app\src\main\AndroidManifest.xml

AndroidManifest.xml 是什么?下面是AI的解答:

`AndroidManifest.xml` 文件是 Android 应用程序项目中的一个关键配置文件。它位于应用项目的根目录下,并定义了应用的元数据、组件、所需权限、硬件和软件功能需求等信息。以下是 `AndroidManifest.xml` 文件通常包含的内容:
1. **包名** (`package`): 应用程序的唯一标识符,通常是反向的域名格式。
```xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
```
2. **应用标签** (`<application>`): 这是 `AndroidManifest.xml` 的主要部分,包含应用的所有组件和属性。
- **应用名称** (`android:label`): 显示给用户的应用名称。
- **应用图标** (`android:icon`): 应用的图标资源。
- **主题** (`android:theme`): 应用的主题样式。
3. **活动** (`<activity>`): 应用中的一个界面屏幕,通常用于与用户交互。
- **意图过滤器** (`<intent-filter>`): 定义了哪些意图可以启动该活动,例如默认启动的 `MAIN` 动作和 `LAUNCHER` 类别。
4. **服务** (`<service>`): 执行后台操作的组件。
5. **广播接收器** (`<receiver>`): 用于响应系统级广播的组件。

6、(在循环中)

CleanCopyDirectory(Path.Combine(UE4BuildPath, "assets"), Path.Combine(UE4BuildGradleMainPath, "assets")); // D:\项目\Intermediate\Android\arm64 /assets 等  拷贝给   项目\Intermediate\Android\arm64 / gradle/src/mainCleanCopyDirectory(Path.Combine(UE4BuildPath, "res"), Path.Combine(UE4BuildGradleMainPath, "res"));CleanCopyDirectory(Path.Combine(UE4BuildPath, "src"), Path.Combine(UE4BuildGradleMainPath, "java")); // Path.Combine(UE4BuildGradleAppPath, "src", "main");

Intermediate\Android\arm64/assets (res,src) 等  拷贝给
Intermediate\Android\arm64/gradle/src/main/assets (res,java)

7、

foreach (string Filename in SourceFiles) // 这些文件是  D:\项目\Intermediate\Android\arm64\gradle  中的文件
{ ……Log.TraceWarning("// *Gradle* (4016), Filenam: {0}", Filename); // 几乎遍历了每一个arm64里的文件  D:\项目\Intermediate\Android\arm64\gradle\app\src\main\libs\x86_64\libtgpa.soif (!File.Exists(DestFilename)){ File.Copy(Filename, DestFilename);}// 其中// Source是 Intermediate/Android\arm64\gradle 中的文件// Dest是 Intermediate/Android\gradle 中的同名文件if (Filename.EndsWith("AndroidManifest.xml")){... 某些关键点的比对,省略bCombinedBundleOK = false; // 若确认差异很大,就认定为“不可CombindBundle”Log.TraceInformation("AndroidManifest.xml files differ too much to combine for single AAB: '{0}' != '{1}'", Filename, DestFilename);break;}…… gradle.properties的比对,同上,若差异很大,可能认定为“不可CombindBundle”。…… 其它原因差异很大,可能认定为“不可CombindBundle”。省略…… 
}

从 arm64\gradle 复制文件给 根gradle。并判断是否“差异大”。

8、

if (bCombinedBundleOK)
{

        UnrealBuildTool.UEDeployAndroid.CreateRunGradle()
创建 rungradle.bat

         RunCommandLineProgramWithExceptionAndFiltering()
打印 Making .aab with Gradle..
调用Gradle打包

} else { 略 }

在我的项目案例中,根gradle和arm64/gradle “差异不大”,将会打在根gradle文件夹。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

在IDEA中运行Mybatis后发现取出的password值为null

问题&#xff1a; 解决方案&#xff1a;修改sql文如下&#xff08;取别名&#xff09; Select("select id,name,pwd as password from user where id #{id}") 重新运行即可

股票基础交易规则!最小变动数量规则!最大数量限制规则!

股票基础交易规则系列 数量规则 01 最小变动数量规则 沪深主板、创业板&#xff1a;单笔申报数量应当为100股或其整数倍。 科创板&#xff1a;单笔申报数量应当不小于200股&#xff0c;1股递增。 北交所&#xff1a;单笔申报数量应当不小于100股&#xff0c;1股递增。 举例…

Selenium自动化测试框架详解

&#x1f345; 点击文末小卡片 &#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 设计思路 本文整理归纳以往的工作中用到的东西&#xff0c;现汇总成基础测试框架提供分享。 框架采用python3 selenium3 PO yaml ddt unittest等技术编写…

ChangeCLIP环境配置

看到有个现成的dockerfile&#xff0c;先试试 ok首先需要root权限的用户 才能用docker&#xff0c;其次要外网&#xff0c;要不然有些东西好像下载不了 &#xff08;失败&#xff09; 那就直接配吧 我看12服务器上有个openmmlab的环境&#xff0c;先基于这个环境吧 # 用lx账…

【MATLAB源码-第272期】基于matlab的OMP算法的毫米波MIMO通信系统的混合波束成形仿真。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 在现代无线通信系统中&#xff0c;随着频谱资源的日益紧张&#xff0c;毫米波&#xff08;mmWave&#xff09;技术成为5G及未来通信系统的重要组成部分。毫米波频段的宽频带提供了远超传统微波频段的频谱资源&#xff0c;能够…

【python】OpenCV—findContours(4.3)

文章目录 1、功能描述2、代码实现3、完整代码4、结果展示5、涉及到的库函数5.1、cv2.Canny5.2 cv2.boxPoints 6、参考 1、功能描述 找出图片中的轮廓&#xff0c;拟合轮廓外接椭圆和外接矩阵 2、代码实现 导入必要的库&#xff0c;固定好随机种子 import cv2 as cv import …

直播推流和拉流--系统篇

今天实现一下直播推流和拉流。服务器端使用opencloudos8系统。顺便把我之前写的小系统弄上去跑跑&#xff0c;搭建个git服务器&#xff0c;使用ssh协议&#xff0c;密钥方式。 先展示一下在iphone上推流效果图 再展示下在谷歌浏览器上的拉流效果图&#xff0c;safari浏览器和微…

安全芯片 OPTIGA TRUST M 使用介绍与示例(基于STM32裸机)

文章目录 目的资料索引硬件电路软件框架介绍数据存储框架移植框架使用 使用示例示例地址与硬件连接通讯测试功能测试 总结 目的 OPTIGA TRUST M 是英飞凌推出的安全芯片&#xff0c;芯片通提供了很多 slot &#xff0c;用于存放各类安全证书、密钥、用户数据等&#xff0c;内置…

数据结构 之 二叉树遍历 ------中序(根)遍历 和 后序(根)遍历(六)

提示&#xff1a;本篇章主要讲解数据结构中树的相关知识。 文章目录 中序&#xff08;根&#xff09;遍历二叉树&#xff08;LTR&#xff09;后序&#xff08;根&#xff09;遍历二叉树&#xff08;LRT)中根遍历二叉树的递归算法 &#xff08;重要&#xff09;后序遍历二叉树的…

数据结构 ——— 二叉树的概念及结构

目录 二叉树的概念 特殊的二叉树 一、满二叉树 二、完全二叉树 二叉树的概念 二叉树树示意图&#xff1a; 从以上二叉树示意图可以看出&#xff1a; 二叉树每个节点的度不大于 2 &#xff0c;那么整个二叉树的度也不大于 2 &#xff0c;但是也不是每个节点都必须有 2 个…

IDEA解决 properties 文件乱码问题

博主介绍&#xff1a; 计算机科班人&#xff0c;全栈工程师&#xff0c;掌握C、C#、Java、Python、Android等主流编程语言&#xff0c;同时也熟练掌握mysql、oracle、sqlserver等主流数据库&#xff0c;具有丰富的项目经验和开发技能。提供相关的学习资料、程序开发、技术解答、…

MySQL 9从入门到性能优化-创建触发器

【图书推荐】《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;》-CSDN博客 《MySQL 9从入门到性能优化&#xff08;视频教学版&#xff09;&#xff08;数据库技术丛书&#xff09;》(王英英)【摘要 书评 试读】- 京东图书 (jd.com) MySQL9数据库技术_夏天又到了…

电子邮件营销平台教程:从零开始营销指南!

电子邮件营销平台功能详解&#xff1f;哪个电子邮件营销平台好&#xff1f; 无论是初创企业还是成熟品牌&#xff0c;掌握电子邮件营销平台的技巧&#xff0c;都能有效提升品牌影响力和销售业绩。MailBing将为你提供一份详尽的电子邮件营销平台教程&#xff0c;帮助你从零开始…

软件行业似乎要消失了

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 软件行业是企业倒闭和裁员降薪的重灾区&#xff0c;其实比网站、站长、电商群体更惨。 据赛迪发布&#xff0c;354家软件上市公司财报数据显示&#xff1a;上半年合计利润6.9亿&#xff0c;同比下跌91.62%&#x…

windows 10 clion配置32位c++环境

主要就是这一个地方&#xff0c;需要32位的mingw32&#xff0c;mingw32可以在红框的蓝色download下载

计算机视觉-对极几何

1 基本概念 对极几何&#xff08;Epipolar Geometry&#xff09;描述的是两幅视图之间的内在射影关系&#xff0c;与外部场景无关&#xff0c;只依赖于摄像机内参数和这两幅视图之间的相对位姿 两视图的对极几何可以理解为图像平面与以基线为轴的平面束相交的几何关系&#xf…

leetcode344. Reverse String

Write a function that reverses a string. The input string is given as an array of characters s. You must do this by modifying the input array in-place with O(1) extra memory. Example 1: Input: s [“h”,“e”,“l”,“l”,“o”] Output: [“o”,“l”,“l”…

ssm016基于 Java Web 的校园驿站管理系统(论文+源码)_kaic

毕 业 设 计&#xff08;论 文&#xff09; 题目&#xff1a;校园驿站管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好…

鸿蒙自定义加载 LoadingDialog

代码如下&#xff1a; Component export struct LoadingDialog {Prop title: stringbuild() {Stack() {Column() {LoadingProgress().color(Color.White).width(100).height(100)Text(this.title).fontSize(18).fontColor(0xffffff).margin({ top: 8 }).visibility(this.title …

【AI开源项目】Dify- 轻松打造可持续运营的 GPT 系列的 AI应用 —— 全面解析LLMOps平台

文章目录 什么是Dify&#xff1f;Dify的名称由来 了解LLMOpsDify的核心功能兼容多种LLMs Dify的优势完全开源核心能力 如何安装Dify快速启动使用Helm Chart在Kubernetes上部署自定义配置 使用Dify创建AI应用第一步&#xff1a;创建应用程序第二步&#xff1a;编写和调试提示词第…