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

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文件夹。

相关文章:

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

两个Gradle工程的现象 在出安卓aab包时&#xff0c;观察到存在以下两个Gradle工程&#xff1a; 1、Intermediate\Android\arm64\gradle &#xff08;称为arm64的Gradle&#xff09; 2、Intermediate\Android\gradle&#xff08;称为根下的Gradle&#xff09; 它们存在一些小…...

淘宝API接口( item_get- 淘宝商品详情查询)

淘宝商品详情查询 API&#xff08;item_detail&#xff09;主要用于获取淘宝商品的详细信息&#xff0c;以下是相关介绍&#xff1a; 请求参数&#xff1a; num_iid&#xff1a;必填参数&#xff0c;代表商品的唯一标识 ID。通过该 ID 可以准确地指定要查询的商品。例如&#…...

Soanrquber集成Gitlab 之 gitlab用户配置和身份验证

集成Gitlab &#xff1a; gitlab用户配置和身份验证 说明&#xff1a; 使得Sonarquber的用户登录与Gitlab的用户登录/认证模块同步 什么是 SonarQube&#xff1f; SonarQube 是一个开源的代码质量管理平台&#xff0c;用于持续检查和分析代码的质量和安全性。它提供了多种功…...

沪深A股上市公司数据报告分析

数据分析报 目录 数据分析报告 1.引言 1.1 背景介绍 1.2 报告目的 1.3 报告范围 1.4 关键术语定义 2. 数据收集与预处理 2.1 数据来源概述 2.2 数据收集过程 2.3 数据预处理步骤 3. 数据可视化 3.1分析地区对公司数量的影响 3.2分析行业分类是否影响公…...

Elasticsearch Search Template 搜索模板

Elasticsearch Search Template 所谓 search template 搜索模板其实就是&#xff1a; 预先定义好查询语句 DSL 的结构并预留参数搜索的时再传入参数值渲染出完整的 DSL &#xff0c;最后进行搜索 使用搜索模板可以将 DSL 从应用程序中解耦出来&#xff0c;并且可以更加灵活的…...

2024年10月-2025年5月 Oracle 19c OCM 考试安排

2024年10月-2025年5月 Oracle 19c OCM 考试安排&#xff1a; 北京考场&#xff1a; 上海考场&#xff1a; 更新时间&#xff1a;2024年10月25日 Oracle 19c OCM往期学员成绩展示&#xff1a; Oracle 19c OCM认证证书&#xff08;电子版&#xff09;...

VMware虚拟机安装KailLinux系统

目录 简介 系统镜像下载 配置虚拟机 安装系统镜像 切换中文界面 后置内容 修改root密码 ssh服务 对互联网的热爱&#xff0c;尝试安装另一套Linux系统。 简介 Kali Linux是一个专为网络安全和渗透测试设计的Linux发行版&#xff0c;它包含了大量安全相关的工具和软件…...

G2 基于生成对抗网络(GAN)人脸图像生成

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 基于生成对抗网络&#xff08;GAN&#xff09;人脸图像生成 这周将构建并训练一个生成对抗网络&#xff08;GAN&#xff09;来生成人脸图像。 GAN 原理概述 …...

R学习笔记-单因素重复测量方差分析

R语言之重复测量方差分析——ezANOVA的使用与解析 - 知乎 单因素重复测量方差分析(One-Way Repeated Measures ANOVA)——R软件实现 - 梦特医数通 ### 清空environment rm(list ls()) ### 加载包 if (!require("tidyverse")) install.packages("tidyverse&quo…...

HTML练习题:彼岸的花(web)

展示效果: 代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>彼岸の花</title><style…...

(蓝桥杯C/C++)——常用库函数

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 一、 二分查找 1.二分查找的前提 2.binary_ search函数 3.lower_bound和upper_bound 二、排序 1.sort概念 2.sort的用法 3.自定义比较函数 三、全排列 1.next p…...

GPT-Sovits-2-微调模型

1. 大致步骤 上一步整理完数据集后&#xff0c;此步输入数据, 微调2个模型VITS和GPT&#xff0c;位置在 <<1-GPT-SoVITS-tts>>下的<<1B-微调训练>> 页面的两个按钮分别执行两个文件: <./GPT_SoVITS/s2_train.py> 这一步微调VITS的预训练模型…...

【数据结构 | PTA】懂蛇语

懂蛇语 在《一年一度喜剧大赛》第二季中有一部作品叫《警察和我之蛇我其谁》&#xff0c;其中“毒蛇帮”内部用了一种加密语言&#xff0c;称为“蛇语”。蛇语的规则是&#xff0c;在说一句话 A 时&#xff0c;首先提取 A 的每个字的首字母&#xff0c;然后把整句话替换为另一…...

Python——自动化发送邮件

在数字化时代&#xff0c;电子邮件是商务沟通和个人联络的重要工具。自动化邮件发送可以节省时间&#xff0c;提高效率。Python&#xff0c;作为一种强大且灵活的编程语言&#xff0c;提供了多种库来支持邮件的自动化发送。本文将详细介绍如何使用Python的smtplib和email库来编…...

MTKLauncher_布局页面分析

文章目录 前言遇到的困难点针对性解决困难 需求相关资料Launcher3 源码 目录简单介绍Launcher3 简介及页面布局分析UI整体架构数据加载布局加载布局加载核心思想device_profiles.xml 加载InvariantDeviceProfileinitGrid(context, gridName)getPredefinedDeviceProfilesinvDist…...

C#实现隐藏和显示任务栏

实现步骤 为了能够控制Windows任务栏&#xff0c;我们需要利用Windows API提供的功能。具体来说&#xff0c;我们会使用到user32.dll中的两个函数&#xff1a;FindWindow和ShowWindow。这两个函数可以帮助我们找到任务栏窗口&#xff0c;并对其执行显示或隐藏的操作 引入命名空…...

基于springboot+vue实现的公司财务管理系统(源码+L文+ppt)4-102

基于springbootvue实现的公司财务管理系统&#xff08;源码L文ppt&#xff09;4-102 摘要 本系统是基于SpringBoot框架开发的公司财务管理系统,该系统包含固定资产管理、资产申领管理、资产采购管理、员工工资管理等功能。公司财务管理系统是一种帮助公司进行有效资金管理、会…...

rnn/lstm

tip&#xff1a;本人比较小白&#xff0c;看到july大佬的文章受益匪浅&#xff0c;现在其文章基础上加上自己的归纳、理解&#xff0c;以及gpt的答疑&#xff0c;如果有侵权会删。 july大佬文章来源&#xff1a;如何从RNN起步&#xff0c;一步一步通俗理解LSTM_rnn lstm-CSDN博…...

袋鼠云产品功能更新报告12期|让数据资产管理更高效

本期&#xff0c;我们更新和优化了数据资产平台相关功能&#xff0c;为您提供更高效的产品能力。以下为第12期袋鼠云产品功能更新报告&#xff0c;请继续阅读。 一、【元数据】重点更新 &#xff5c;01 元数据管理优化&#xff0c;支持配置表生命周期 之前系统中缺少一个可以…...

MATLAB——入门知识

内容源于b站清风数学建模 目录 1.帮助文档 2.注释 3.特殊字符 4.设置MATLAB数值显示格式 4.1.临时更改 4.2.永久改 5.常用函数 6.易错点 1.帮助文档 doc sum help sum edit sum 2.注释 ctrl R/T 3.特殊字符 4.设置MATLAB数值显示格式 4.1.临时更改 format lon…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

挑战杯推荐项目

“人工智能”创意赛 - 智能艺术创作助手&#xff1a;借助大模型技术&#xff0c;开发能根据用户输入的主题、风格等要求&#xff0c;生成绘画、音乐、文学作品等多种形式艺术创作灵感或初稿的应用&#xff0c;帮助艺术家和创意爱好者激发创意、提高创作效率。 ​ - 个性化梦境…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

Java 语言特性(面试系列1)

一、面向对象编程 1. 封装&#xff08;Encapsulation&#xff09; 定义&#xff1a;将数据&#xff08;属性&#xff09;和操作数据的方法绑定在一起&#xff0c;通过访问控制符&#xff08;private、protected、public&#xff09;隐藏内部实现细节。示例&#xff1a; public …...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

并发编程 - go版

1.并发编程基础概念 进程和线程 A. 进程是程序在操作系统中的一次执行过程&#xff0c;系统进行资源分配和调度的一个独立单位。B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更小的能独立运行的基本单位。C.一个进程可以创建和撤销多个线程;同一个进程中…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...