我尝试通过 productFlavors 构建不同的 Android 应用程序包。为了保存和测试文件,我需要一个固定的文件名。
对于 APK,我有以下工作代码:
applicationVariants.all { variant ->
if (variant.buildType.name.equals("release")) {
variant.outputs.all { output ->
outputFileName = "${applicationId}-${versionCode}-${variant.flavorName}.apk"
}
}
if (variant.getBuildType().isMinifyEnabled()) {
variant.assemble.doLast {
copy {
from variant.mappingFile
into variant.outputs[0].outputFile.parent
rename { String fileName ->
"${applicationId}-${versionCode}-${variant.flavorName}-mapping.txt"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但这不适用于捆绑。我尝试使用此代码使其正常工作:
tasks.whenTaskAdded { task ->
if (task.name.startsWith("bundle")) {
def renameTaskName = "rename${task.name.capitalize()}Aab"
def flavor = task.name.substring("bundle".length()).uncapitalize()
tasks.create(renameTaskName, Copy) {
println android.defaultConfig.versionName
def applicationId = android.defaultConfig.applicationId
def versionCode = android.defaultConfig.versionCode
def path = "${buildDir}/outputs/bundle/${flavor}/"
from(path)
include …Run Code Online (Sandbox Code Playgroud) 几个月前,我的一个团队成员选择了这个可怕的应用捆绑计划。
2周前,我们发生了重大事件,AAB文件使应用程序崩溃,而经过测试的APK文件没有崩溃。在发现额外的步骤bundletool.jar之前,我们无法进行测试,这是一个噩梦。
我的问题是,一旦我们不小心选择加入该系统,该如何退出?我们只希望使用简单的APK。
我正在将我的 CI 过程从生成 APK 文件切换到 App Bundle。我的管道中的一个阶段将在生成已签名的二进制文件后,转储签名并验证 APK 上的签名,以确保在继续之前正确签名。
> apksigner verify --print-certs my-signed-binary.apk
Signer #1 certificate DN: CN=<NAME>, OU=<GROUP>, O=<COMPANY>, L=<CITY>, ST=<STATE>, C=<COUNTRY>
Signer #1 certificate SHA-256 digest: <DIGEST1>
Signer #1 certificate SHA-1 digest: <DIGEST2>
Signer #1 certificate MD5 digest: <DIGEST3>
Run Code Online (Sandbox Code Playgroud)
一旦生成,是否有等同于在整个 App Bundle 上转储签名的方法?
我尝试使用 jarsigner,但最终输出了数百行。
> jarsigner -verbose -verify -certs my-signed-binary.aab
...
smk 12 Wed Dec 31 16:00:00 PST 1969 base/assets.pb
>>> Signer
X.509, CN=<NAME>, OU=<GROUP>, O=<ORGANIZATION>, L=<CITY>, ST=<STATE>, C=<COUNTRY> (myapp)
[certificate is valid from 5/31/13 1:27 …Run Code Online (Sandbox Code Playgroud) 使用应用程序包时,存在用户将自定义 APK“旁加载”到不兼容设备上的风险。这可能会导致崩溃,因为所需的密度/语言将不存在。
\n\nMissingSplitsManager为了解决这个问题, Google Play Core 中有一个方便的工具。这会在启动时向用户显示有用的错误,而不是崩溃。需要做的就是将以下内容添加到应用程序类中:
override fun onCreate() { \n if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {\n return\n }\n super.onCreate()\n} \nRun Code Online (Sandbox Code Playgroud)\n\n此检查非常容易实现,之前可以在https://developer.android.com/guide/app-bundle/sideload-check上找到详细说明。到处都有指向此内容的链接,例如在 Realm 问题中或在MissingSplitsManager 文档的顶部。
\n\n但是,此链接现在重定向到“已知问题”部分,其中非常模糊:
\n\n\n\n\n部分安装旁加载应用程序\xe2\x80\x94,即未使用 Google Play 商店安装且缺少一个或多个必需的拆分 APK\xe2\x80\x94 的应用程序在所有 Google 认证设备和运行 Android 10 的设备上失败( API 级别 29) 或更高。通过 Google Play 商店下载您的应用程序时,Google 会确保安装该应用程序的所有必需组件。
\n
所以发生了什么事?为什么不再提及库的简单检查,甚至在库的文档中也是如此。
\n\n也许该库存在一些未记录的问题?也许 Google 根本不想帮助侧载?
\n我一直在尝试构建我的应用程序包的新版本,但它不会使用相同的密钥来构建它。我点击“Build”>“Generate Signed Bundle or APK...”>选择“Android App Bundle”>“Next”,然后选择我的密钥,输入相同的密钥存储密码、相同的密钥别名,检查密钥存储路径两次在这种情况下,单击“下一步”>“选择发布”>“完成”,但没有任何反应。我没有收到错误或任何类型的提示,什么也没有。
我该如何解决?
编辑:我找到了答案,别名不一样,如果密钥别名不同,Android Studio 甚至不会尝试构建新版本
有谁知道如何使用新的密钥库从命令行签名.aab文件?此处的文档提到,我们可以使用jarsigner从命令行对应用程序包进行签名。但是我找不到命令行?有人知道命令行吗?
将捆绑包上传到Google Play时出现此错误:
You uploaded an APK with an invalid signature (learn more about signing). Error from apksigner:
Run Code Online (Sandbox Code Playgroud)
我尝试使用以下命令对应用程序捆绑包进行签名:
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore xample.jks bundle.aab keystoreAlias
Run Code Online (Sandbox Code Playgroud)
非常感谢你。
我正在使用新的应用程序捆绑包格式(aab)发布应用程序。该应用程序包括一些用于armeabi-v7a的本地库。当我在arm64-v8a架构上通过Google Play安装该应用程序时,它不包含没有arm64-v8a so本地文件的本机库。
根据此/sf/answers/2773574961/,armeabi-v7a库应在arm64-v8a设备上运行(并且通过adb安装时工作正常,因此确实可以工作)。
Google Play控制台会根据架构,屏幕密度等显示不同的apk。从apk大小中,我可以清楚地看出哪些不包含本机库。我还使用本机libs Monitor应用程序来分析已安装的apk,并且它显然不包括我需要的本机库(如果该应用程序具有arm64-v8a so文件,则它包括arm64-v8a本机库,但如果只有armeabi,则不包括-v7a版本)。
我的gradle构建文件包括以下用于捆绑包配置的小段代码:
bundle {
language {
enableSplit = false
}
density {
enableSplit = true
}
abi {
enableSplit = true
// include 'armeabi', 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
}
}
Run Code Online (Sandbox Code Playgroud)
现在这是我的问题:是否有办法告诉构建工具在每个apk中都包括“次优”本机库,其次是在特定体系结构上运行的最近版本?
PS:如果我为abi设置enableSplit = false,则它将包括本机库(如预期的那样),但不幸的是,对于包括x86在内的所有平台(仅20MB大)...
我正在尝试实现动态投放类型的应用。首先,我创建了一个新项目,之后创建了用于此动态步骤的模块
从菜单栏中选择“文件”>“新建”>“新模块”,然后在“创建新模块”对话框中选择“动态功能模块”,然后单击“下一步”。
文件夹的结构
我创建了类,想要访问用于布局,可绘制文件夹的资源文件夹。
同样在主模块gradle中实现
实现'com.google.android.play:core:1.2.0'和dynamicFeatures = [“:dynamic_feature”]
但是获取动态模块 错误显示错误
错误:找不到符号变量activity_main
错误:找不到符号变量iv_forward
错误:找不到符号变量seekBar
https://developer.android.com/studio/projects/dynamic-delivery https://proandroiddev.com/dynamic-feature-module-android-ondemand-module-android-app-bundle-ea0d872b32d
android app-bundle android-layout android-module android-app-bundle
我有ConstraintLayout一个XML布局中,它包含了3次和Barrier,它们是button2,textView2,barrier2,和button3。正如预期的那样,button3成功地放置在button2和 下textView2,受使用 约束barrier2。然而,当在动态特征模块中使用时,它似乎没有引用约束视图(button2和textView2),所以它坚持顶部。button3
这些屏幕截图显示它是成功的基础模块,但在动态功能模块中不起作用:
基本功能和动态功能中的 XML 布局如下所示:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TextView 2"
app:layout_constraintStart_toEndOf="@id/button2"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.Barrier
android:id="@+id/barrier2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:barrierDirection="bottom"
app:constraint_referenced_ids="button2,textView2" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button 3"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/barrier2" …Run Code Online (Sandbox Code Playgroud) 我有一个带有数据绑定的多模块项目(我使用Android App Bundle),ViewModels。但是,当我启用Proguard该应用程序时,发生以下错误:
java.lang.RuntimeException: Unable to start activity ComponentInfo{...MyActivity}: java.lang.IllegalStateException: DataBindingUtil.setConte… R.layout.my_activity) must not be null
Caused by: java.lang.IllegalStateException: DataBindingUtil.setConte… R.layout.my_activity) must not be null
at MyActivity.onCreate(MyActivity.kt:38)
当我删除模块并创建一个app模块时,一切正常。当我禁用时Proguard,它也可以正常工作。这是我的一部分proguard-rules.pro:
-dontwarn android.databinding.**
-keep class android.databinding.** { *; }
-keep class com.example.module1.databinding.** { *; }
-keep class com.example.module2.databinding.** { *; }
Run Code Online (Sandbox Code Playgroud)
在build.gradle:
minifyEnabled true
useProguard true
Run Code Online (Sandbox Code Playgroud)
因此错误指向以下代码行:
val binding: com.example.module1.databinding.MyActivityBinding =
DataBindingUtil.setContentView(this, R.layout.my_activity)
Run Code Online (Sandbox Code Playgroud)
也许有什么想法如何解决?