我编写了一个支持多语言的小型演示应用程序。然后我构建了一个应用程序包并将其上传到 Play 商店。
当我在系统设置中更改语言设置时,将触发 Play 商店为我的应用程序下载附加语言包。
但问题是,如果我的应用程序在下载完成之前位于前台,下载将停止,并且不会继续下载,直到我有一个新的游戏商店下载任务,例如请求动态功能模块,或者再次更改语言设置...而且似乎当语言包下载并安装成功后,我的应用程序将被自动杀死。这使得 App Bundle 在切换语言时非常难以使用。
是否可以将通过 Android 应用程序包生成的多个 apk 合并到一个可安装/可分发的 apk 中?
我尝试通过 adb install-multiple 安装,但以这种方式,它是不可分发的。
我在通过 Android Studio 在新的 Android Q Beta 1 上安装我的应用程序时遇到问题。看起来就像这个问题。
答案建议android:extractNativeLibs在 Manifest 中进行设置,它确实解决了安装问题。有趣的是,如果它设置为true或false(无论是案例工作)都没有关系,但我必须设置它。
由于 Realm 是我的应用程序中包含的唯一本机代码,我想问一下我是否应该设置这个标志。
到现在为止,我并不需要它,但这个和这个告诉我,它实际上是一件好事,将它设置为false。它甚至指出:
在构建 AAB 时,它默认将 extractNativeLibs 标志设置为“false”。
有了这个集合,使用 APK 或 AAB应该没问题,但本机代码必须是 zipaligned。所以还有一个问题:
领域二进制文件是否正确压缩?
或者一般来说:在使用领域时有什么建议吗?
当这个标志一切正常时(而且我以前的 AAB 工作得很好),这里唯一的问题似乎是 Android Q 在安装(调试-)APK 时需要这个标志,对吗?
我按照本指南将检查集成到我的应用程序中,以防止在使用 Android App Bundles(用于丢失资源)时在运行时崩溃。
我onCreate()在超级调用之前的方法中将以下代码添加到我的应用程序类中:
if (MissingSplitsManagerFactory.create(this).disableAppIfMissingRequiredSplits()) {
// Skip app initialization.
return
}
Run Code Online (Sandbox Code Playgroud)
这在我自己的测试设备上没有问题。但是,如果我将 Android App Bundle 上传到 Google Play,预发布报告中的某些设备会出现此异常:
FATAL EXCEPTION: main
Process: com.example, PID: 25603
java.lang.RuntimeException: Unable to create application com.example.App: java.lang.RuntimeException: Package manager has died
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4858)
at android.app.ActivityThread.access$1600(ActivityThread.java:163)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1423)
at android.os.Handler.dispatchMessage(Handler.java:102)com.example
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5585)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by: java.lang.RuntimeException: Package manager has died
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:136)
at Cfa.a(SourceFile)
at com.example.App.onCreate(SourceFile:17)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:1014)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4855)
... …Run Code Online (Sandbox Code Playgroud) android android-package-managers google-play android-application-class android-app-bundle
如果我们有以下参数,尝试使用新的 App Bundle 格式发布新应用程序(它是一个启动器,这也很重要)可能会很棘手:
ContentProvider一个子库这种方法导致了几个问题:
由于找不到类的问题,ContentProvider模块中的 无法启用,应在主清单中禁用它,然后在下载动态功能并可用于主应用程序后以编程方式启用。
如果我们使用SplitCompatInstall,该功能可以很好地下载,但实际上它被模拟为第一个并且没有安装,这会导致下一个问题
如果应用程序需要重新启动,因为 contentProvider 已以编程方式启用,并且由于它是持久的,所以它会尝试重新启动。失败是因为动态功能尚未安装(实际上是重新安装的SplitCompat.install()),因此类加载器无法找到相应的类并且应用程序崩溃。
如果应用程序是启动器,由系统自动重新启动,则会出现崩溃循环!
因此,对于这种特殊情况,我建议不要使用SplitCompat.install
Prefer using deferredInstall()which download the feature apks,然后通过 android play.core 发布一个正确安装的任务。
此策略的缺点是您无法控制何时安装应用程序功能。您可能需要等待您的应用程序进入后台,以便它安装新功能。
如果您的应用程序是一个始终有一个正在运行的线程的启动器,它可能永远不会发生,即使在重新启动时也是如此(我所看到的)。最后,当您通过 Playstore 更新您的应用程序时,它最终会安装所有动态功能 apk(以及相关组件,例如ContentProvider)
我愿意讨论这个话题
启用或禁用的代码ContentProvider:
public static void enableMyProviderForDynamicFeature(final Context context, final boolean enable) {
Log.d("DebugDynamicFeature", "com.duapps.ad.stats.MyProvider"+ (enable?" enabling":" disabling"));
final ComponentName componentName = new ComponentName(context, "com.duapps.ad.stats.MyProvider");
final PackageManager packageManager = context.getPackageManager();
packageManager.setComponentEnabledSetting(componentName, enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED …Run Code Online (Sandbox Code Playgroud) 使用 root,我知道对于单个 APK 文件,我们可以使用“libsu”库(此处)进行安装:
val installResult = Shell.su("pm install -t \"$filePath\"").exec()
Run Code Online (Sandbox Code Playgroud)
如果失败了(在新的 Android 版本上失败了,不确定是哪个版本),如下(在这里写下):
val installResult = Shell.su("cat \"$filePath\" | pm install -t -S ${apkSource.fileSize}").exec()
Run Code Online (Sandbox Code Playgroud)
我还知道,在安装拆分 APK 文件时,事情会变得非常混乱(如此处所示)。首先,您需要使用“pm install-create”命令创建一个会话:
var sessionId: Int? = null
run {
val sessionIdResult =
Shell.su("pm install-create -r -t").exec().out
val sessionIdPattern = Pattern.compile("(\\d+)")
val sessionIdMatcher = sessionIdPattern.matcher(sessionIdResult[0])
sessionIdMatcher.find()
sessionId = Integer.parseInt(sessionIdMatcher.group(1)!!)
Log.d("AppLog", "sessionId:$sessionId")
}
Run Code Online (Sandbox Code Playgroud)
然后你必须“推送”每个 APK 文件,如下所示:
for (apkSource in fileInfoList) {
val filePath = File(apkSource.parentFilePath, apkSource.fileName).absolutePath
Log.d("AppLog", "installing …Run Code Online (Sandbox Code Playgroud) android adb android-install-apk android-app-bundle android-10.0
我们的 .aab 文件大小已超过 150 MB。我想知道我们是否可以在 Play 商店上发布超过 150 MB 文件的 .aab 文件。
根据开发人员文档: https: //developer.android.com/guide/app-bundle/
使用 Android App Bundle 发布还将应用程序大小限制增加到 150MB,而无需使用 APK 扩展文件。请记住,此限制仅适用于实际下载大小,不适用于发布大小。因此,用户可以下载最大 150MB 的应用程序
根据文档,我了解到我们可以发布超过150 MB的.aab,但是当用户从Play Store下载APK时,APK的大小应该在150 MB的限制之内。
我这里的理解正确吗?
我正在开发一个移动应用程序并使用react-native进行开发。我可以通过以下方式在我的模拟器上成功运行该项目
\n\nreact-native run-android \nRun Code Online (Sandbox Code Playgroud)\n\n我可以使用命令成功发布捆绑包
\n\n./gradlew bundleRelease\nRun Code Online (Sandbox Code Playgroud)\n\n我什至可以成功地将我的应用上传到 Google Play 商店。\n问题是某些设备无法安装该应用。它会失败。
\n\n在互联网上搜索后,我发现问题是不同设备上的各种不同的 cpu 架构(据我所知)。我的模拟器使用 32 位 cpu (x86),并且构建在我的模拟器上成功运行。
\n\n我没有 Android 设备,因此我发现调试错误的最佳方法是使用 Firebase 的“测试实验室”并观察输出。
\n\n我相信除了CPU架构之外还有另一个问题,那就是Hermes。我在app/build.gradle中禁用了hermes,但是当我发布一个包并在Firebase测试实验室上测试它时,应用程序将失败并给我这个输出;
\n\njava.lang.UnsatisfiedLinkError: couldn\'t find DSO to load: libhermes.so\n FATAL EXCEPTION: create_react_context\nProcess: com.lockerapp, PID: 18180\njava.lang.UnsatisfiedLinkError: couldn\'t find DSO to load: libhermes.so\n at com.facebook.soloader.SoLoader.doLoadLibraryBySoName(SoLoader.java:738)\n at com.facebook.soloader.SoLoader.loadLibraryBySoName(SoLoader.java:591)\n at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:529)\n at com.facebook.soloader.SoLoader.loadLibrary(SoLoader.java:484)\n at com.facebook.hermes.reactexecutor.HermesExecutor.<clinit>(HermesExecutor.java:20)\n at com.facebook.hermes.reactexecutor.HermesExecutorFactory.create(HermesExecutorFactory.java:27)\n at com.facebook.react.ReactInstanceManager$5.run(ReactInstanceManager.java:949)\n at java.lang.Thread.run(Thread.java:764)\nRun Code Online (Sandbox Code Playgroud)\n\n这是我的环境;
\n\nSystem:\n OS: macOS 10.14.4\n CPU: (4) x64 Intel(R) Core(TM) i5-4278U …Run Code Online (Sandbox Code Playgroud) 我有一个仅在 64 位配置下运行的应用程序。我已将以下内容放入 abi 过滤器中
splits{
abi {
enable true
reset()
include "x86_64", "arm64-v8a"
universalApk true
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我上传 alpha track 应用程序时,我看到了这个:
如何确保我的应用程序不可用于 64 位设备以外的其他设备下载?
我已经使用 PWA2APK 将我的 React 应用程序的第一个版本上传到 Google Play。它工作得很好。但是每次我尝试通过上传新版本来更新应用程序时,我都会得到以下信息:
You uploaded an APK that is not signed with the upload certificate. You must use the same certificate. The upload certificate has fingerprint:
SHA1: *******************
and the certificate used to sign the APK you uploaded has fingerprint:
SHA1: **********************
Your APK or Android App Bundle needs to have the package name ****(name_of_previous_version)****.
You need to use a different version code for your APK or Android App Bundle because you already have one with …Run Code Online (Sandbox Code Playgroud) apk google-play reactjs progressive-web-apps android-app-bundle
android ×8
google-play ×3
64-bit ×2
adb ×1
android-10.0 ×1
apk ×1
build ×1
react-native ×1
reactjs ×1
realm ×1