大型网站开发基本流程,wordpress插件统计,设立,网站模板带手机站摘要
本文学习了aab的基本概念以及UE4中产生aab的构建原理。 从官网了解基本概念 官网#xff1a;Android Developers 1、什么是aab#xff1f;
.aab包形如#xff1a; 2021年7月#xff0c;在Google Play应用程序中#xff0c;已经有数千个应用程序率先跟进了AAB格式。…摘要
本文学习了aab的基本概念以及UE4中产生aab的构建原理。 从官网了解基本概念 官网Android Developers 1、什么是aab
.aab包形如 2021年7月在Google Play应用程序中已经有数千个应用程序率先跟进了AAB格式。谷歌宣布从2021年8月份开始所有提交到Google Play商店的新应用必须采用AAB格式。
全称Android App Bundles。谷歌在2018年启用了AAB新格式AAB全称为Android App Bundles”谷歌声称这种新格式将使应用程序文件更小意味着aab分布式应用程序比通用apk平均少占用15% 的空间。更重要的是它拓展了应用程序捆缚包的定义只包含运行App时的必要代码。也就是说下载了一部分之后App就可以直接运行无需等待下载完成再安装。 2、什么是PAD
全称 Play Asset Delivery它是能够打包出 aab 的组件。 3、三个分发模式是什么
install-time 资源包在用户安装应用时分发。这些资源包以拆分 APKAPK 集的一部分的形式提供。它们也称为“预先”资源包您可以在应用启动时立即使用这些资源包。这些资源包会增加 Google Play 商店上列出的应用大小。用户无法修改或删除这些资源包。fast-follow 资源包会在用户安装应用后立即自动下载用户无需打开应用即可开始 fast-follow 下载。下载过程中用户仍然可以进入应用。这些资源包会增加 Google Play 商店上列出的应用大小。on-demand 资源包会在应用运行时下载。
Google Play 商店会以归档文件而非拆分 APK的形式提供配置为 fast-follow 和 on-demand 的资源包。然后这些资源包会在应用的内部存储空间中展开。 4、资源更新的方式
更新应用时install-time Asset Pack 会作为基础应用更新的一部分进行更新开发者无需执行任何操作。
对于 fast-follow 和 on-demand Asset Pack 的应用更新则遵循以下步骤
1 系统将应用的补丁程序包括所有资产下载到设备上的安全位置。
2 更新应用二进制文件这包括所有 install-time Asset Pack。
3 之前下载的所有 Asset Pack 变为无效。
4 将资源的补丁复制并应用到存储在应用内部存储空间中的资源。 5、什么是apksapks即apk split分散的apk。
现在我们从谷歌商店上下载的应用多半都是apks格式的。
apks格式的安装包就是使用了Android App BundleAAB技术生成的安装包。
这种技术实际上就是将apk文件拆分成多个小包再根据当前的设备选择适当的文件下载安装。
通过这种技术谷歌商店就可以根据我们的设备生成一个适合当前设备的安装包例如使用大屏幕设备的用户就不需要下载小屏幕的资源使用arm v8架构设备的用户就不需要下载arm v7架构的资源当然还存在x86架构的使用中文的用户就不需要下载其他的语言文件这样就可以在实现更多功能的同时减小app占用空间的大小。并且为开发者提供了灵活的分发方式和极高的性能。同时apks将不再支持使用obb数据包拓展软件这也意味着使用obb数据包的xapk已经成为过去式了。 6、互斥性。
打apk就不应该打aab、apks打aab、apks就不应该打apk。aab、apks应该同时出现。 开关 在设置中找到开关 “Generate bundle (AAB)”打开它表示生成Google的AAB。 位置是
EngineSource\Engine\Source\Runtime\Android\AndroidRuntimeSettings\Classes\AndroidRuntimeSettings.h // Enables generating AAB bundleUPROPERTY(GlobalConfig, EditAnywhere, Category App Bundles, Meta (DisplayName Generate bundle (AAB)))bool bEnableBundle;
它影响了 EngineSource\Engine\Source\Programs\UnrealBuildTool\Platform\Android\UEDeployAndroid.cs 中的逻辑大致是
// 位于 private void MakeApk(...) 方法中if (!bEnableBundle) // 如果打的是 apk
{ …… RunCommandLineProgramWithExceptionAndFiltering(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin \ GradleScriptPath \ GradleOptions ShellParametersEnd, Making .apk with Gradle...);……
}
else // 如果打的是aab、apks
{ ……RunCommandLineProgramWithExceptionAndFiltering(UE4BuildGradlePath, ShellExecutable, ShellParametersBegin \ GradleScriptPath \ GradleOptions ShellParametersEnd, Making .aab with Gradle...);……
}
所谓RunCommandLineProgramWithExceptionAndFiltering字面上执行的是
// 【书签1】
2024-10-12 15:14:19:037 : VERBOSE:
2024-10-12 15:14:19:037 : Running: cmd.exe /c {我的项目}\Intermediate\Android\gradle\rungradle.bat --stacktrace :app:bundleDebug --init-script init.gradle --profile
从字面意思 rungradle.bat 可以得知无论是打 .apk 还是打 .aab/.apks都是用 Gradle 来打包的。Gradle是安卓的构建打包管理工具。关于Gradle推荐阅读《实战Gradle中文完整版》这本书。 rungradle.bat
这个脚本位于 {我的项目}\Intermediate\Android\gradle\.gradle 目录它是 Engine\Source\Programs\UnrealBuildTool\Platform\Android\UEDeployAndroid.cs 生成出来的。内容如下
echo off
setlocal
set GRADLEPATH%~dp0
set GRADLE_CMD_LINE_ARGS
:setupArgs
if %1 goto doneStart
set GRADLE_CMD_LINE_ARGS%GRADLE_CMD_LINE_ARGS% %1
shift
goto setupArgs:doneStart
subst Z: %CD%
pushd Z:
call %GRADLEPATH%\gradlew.bat %GRADLE_CMD_LINE_ARGS%
set GRADLEERROR%ERRORLEVEL%
popd
subst Z: /d
exit /b %GRADLEERROR%它调用的是gradlew.bat在日志中会衔接Gradle的日志如下 Package
MakeApk函数包括了“生成apk”与“生成.aab、.apks”的功能MakeApk函数发生在 UE4的package阶段。具体的调用过程示意图 【书签1】的日志就是在这个过程中间来的见 UEDeployAndroid.cs 中。尽管叫做 UEDeployAndroid.cs 但Package阶段会调用它。 众所周知Package步骤对应的脚本是 %EnginePath%\Engine\Build\BatchFiles\RunUAT.bat BuildCookRun -project%ClientPath%\%ProjectName%.uproject -noP4 -platformAndroid -client -clientconfig%TargetBuildConfig% -cookflavor%COOK_FLAVOR% %DISTRIBUTION% -skipcook -pak -compressed -stage -NoDebugInfo -package -ignorejunk -nocompile -archive -archivedirectory%ClientPath%\Saved\Archived -manifests -Verbose 这里参数很多不是这里的重点。这里说一个技巧如何让【书签1】所对应的c#脚本能够输出verbose日志呢做法是为 RunUAT.bat 脚本传参 -Verbose如上面命令的末尾处。
而Gradle的日志可以在哪里看呢
打AAB包时将会在这个位置 C:\android_build_tools\gradle-4.1-rc-2\daemon\7.2 gradle所在环境产生日志文件。 UE4中的Gradle工程
UE4的Gradle工程位于 {我的项目}\Intermediate\Android\gradle 结构如下 我在查一些无聊的问题下面两个问题时发现清除UE4的Intermediate、Binaries目录能够有效果推测是Gradle工程脏了导致的因此删除Gradle工程是一个好的选择毕竟它在Intermediate中可以安全地删除删除后UE4会重新产生Gradle工程。
问题1“main.obb.png”出现在.aab的base目录中而不是在obbassets目录中
问题2.apk、.aab|.apks 都会错误地同时出而应该只出apk或只出aab|apks GooglePAD_APL.xml
在EngineSource下GooglePAD 是谷歌生成.aab的模块。GooglePAD_APL.xml 是其中一个中间作用文件它搭建了 UE4 到 Gradle 的桥梁具体的关系如下 上图只是简单阐述下面将会仔细理解GooglePAD_APL.xml。接下来我描述的方式是贴一段文件内容然后接一些解释。注意并非所有的内容都贴出来了。 ?xml version1.0 encodingutf-8? root xmlns:androidhttp://schemas.android.com/apk/res/android init log textGooglePAD Plugin Init/ setBoolFromProperty resultbEnabled iniEngine section/Script/GooglePADEditor.GooglePADRuntimeSettings propertybEnablePlugin defaultfalse/ setBoolFromProperty resultbOnlyDistribution iniEngine section/Script/GooglePADEditor.GooglePADRuntimeSettings propertybOnlyDistribution defaulttrue/ 依据 /Script/GooglePADEditor.GooglePADRuntimeSettings 的UE4配置来设置变量值。 !-- NDK path -- setString resultNDKVersion valuendk21.4.7075529/ 声明一个字符串变量。 if conditionbEnabled true !-- disable if app bundle disabled -- if conditionbEnableBundle false log textDisabled because not generating AAB bundle/ setBool resultbEnabled valuefalse/ /false /if 等价于
if bEnabled: if not bEnableBundle: bEnabled False当if else语句多起来时这种描述方式会让人抓狂。 resourceCopies log textCopying libplaycore.so and proguard files/ !-- note: have to stage this since we linked it -- copyFile src$S(AbsPluginDir)/../ThirdParty/play-core-native-sdk/libs/$S(Architecture)/$S(NDKVersion)/c_shared/libplaycore.so dst$S(BuildDir)/libs/$S(Architecture)/libplaycore.so / isDistribution copyDir src$S(AbsPluginDir)/../ThirdParty/play-core-native-sdk/proguard dst$S(BuildDir)/gradle/app/proguard / /isDistribution /resourceCopies 一段和资源拷贝有关的逻辑。 settingsGradleAdditions if conditionbEnabled true insert ![CDATA[ // generate mainobb assetpack if (OBB_FILECOUNT.toInteger() 0) { File obbfile new File(OBB_FILE0) …… ]] ![CDATA[ 后面的内容直到 ]] 是XML语言中的表示纯粹字符串。这段表示对 settings.gradle 追加字符串稍后会介绍 settings.gradle。 gameActivityOverrideAPKOBBPackaging if conditionbEnabled true insert ![CDATA[ // for GooglePAD (use upfront for main.obb.png) assetPackManager AssetPackManagerFactory.getInstance(this); 表示追加字符串到 gradle\app\src\main\java\com\epicgames\ue4\GameActivity.java 中。GameActivity.java是运行时的逻辑。也许你会好奇我如何得知它们会拷贝给 GameActivity.java。我的做法是在整个Gradle工程中搜索 ![CDATA[ 后面的字符串。 settings.gradle
经过Package执行后settings.gradle的内容成为了
rootProject.nameapp
include :app
include :downloader_library
include :GCloud
include :GCloudCore
include :permission_library
include :PluginCrosCurl
include :TDM
include :TssSDK
// generate mainobb assetpack
if (OBB_FILECOUNT.toInteger() 0) {File obbfile new File(OBB_FILE0)if (obbfile.exists()) {println Creating install-time assetpack for GooglePAD: assetpacks/install-time/obbassetsfile(assetpacks/install-time/obbassets/src/main/assets).mkdirs()def assetBuildGradle apply plugin: com.android.asset-packassetPack {packName obbassetsdynamicDelivery {deliveryType install-timeinstantDeliveryType install-time}
}def assetBuildGradleFile new File(assetpacks/install-time/obbassets/build.gradle)assetBuildGradleFile.write(assetBuildGradle)def destobbfile new File(assetpacks/install-time/obbassets/src/main/assets/main.obb.png)if (destobbfile.exists()) {destobbfile.delete()}def srcobbStream obbfile.newDataInputStream()def dstobbStream destobbfile.newDataOutputStream()dstobbStream srcobbStreamsrcobbStream.close()dstobbStream.close()}
}// add the assetpacks
def assetpacksDir new File(assetpacks/install-time)
if (assetpacksDir.exists()) assetpacksDir.eachDir {println :assetpacks:install-time: it.nameinclude :assetpacks:install-time: it.name
}
assetpacksDir new File(assetpacks/fast-follow)
if (assetpacksDir.exists()) assetpacksDir.eachDir {println :assetpacks:fast-follow: it.nameinclude :assetpacks:fast-follow: it.name
}
assetpacksDir new File(assetpacks/on-demand)
if (assetpacksDir.exists()) assetpacksDir.eachDir {println :assetpacks:on-demand: it.nameinclude :assetpacks:on-demand: it.name
}在这其中我们看到特定的文件夹被设置成了开头我们说的“install-time”等拉取方式。 未完。