Android 打包AAB+PAD(java篇)(下)

简介: Play Core API 集成安装时分发快速跟进式分发和按需分发查看状态获取有关资源包的下载信息安装监控下载状态下载内容较大获取资源包取消请求移除资源包获取多个资源包的位置相关推荐Android aab打包Android App Bundle 已取代 APK

Play Core API 集成


       请务必先将 Play Core 库添加到你的项目中。


       Play Core Java API 提供了用于请求资源包、管理下载内容和获取资源的 AssetPackManager 类。请务必先将 Play Core 库添加到你的项目中。 你可以根据希望获取的资源包的分发类型来实现此 API。这些步骤如以下流程图所示。


     注意: 用于获取 install-time Asset Pack 的 API 与用于获取 fast-follow on-demand Asset Pack 的 API 不同


微信图片_20220521111242.png


安装时分发


       配置为 install-time 的资源包可以在应用启动后立即使用。使用 Java AssetManager API 获取在此模式下提供的资产:


import android.content.res.AssetManager;
...
Context context = createPackageContext("com.example.app", 0);
AssetManager assetManager = context.getAssets();
InputStream is = assetManager.open("asset-name");


快速跟进式分发和按需分发


       以下几部分介绍了如何在下载 Asset Pack 前获取其相关信息、如何调用 API 以开始下载,以及之后如何获取已下载的 Asset Pack。这几部分适用于 fast-follow 和 on-demand Asset Pack。


查看状态


       每个资源包都存储于应用的内部存储空间内单独的文件夹中。使用 getPackLocation() 方法确定 Asset Pack 的根文件夹。此方法会返回以下值:


  • 有效的AssetPackLocation对象:资源包根文件夹位于 assetsPath(),现已可立即获取


  • null:未知 Asset Pack 或资产无法使用


      注意:请勿依赖在两次应用启动之间的间隔时间内缓存的 Asset Pack 位置。应用应在每次启动时始终检查是否存在 Asset Pack。Asset Pack 可能会因应用更新或用户清除应用数据而变为无效。


获取有关资源包的下载信息


       在提取资源包之前,应用必须披露下载内容的大小。使用getPackStates() 方法确定下载内容的大小,以及资源包是否已在下载。


Task<AssetPackStates> getPackStates(List<String> packNames)


      getPackStates() 是用于返回任务的异步方法。该任务的结果包含一个 AssetPackStates 对象。AssetPackStates 对象的 packStates() 方法会返回一个 Map<String, AssetPackState>。此映射包含所请求的每个 Asset Pack 的状态,按其名称进行键控:


Map<String, AssetPackState> AssetPackStates#packStates()


最终请求如下所示:


final String assetPackName = "myasset";
assetPackManager
    .getPackStates(Collections.singletonList(assetPackName))
    .addOnCompleteListener(new OnCompleteListener<AssetPackStates>() {
        @Override
        public void onComplete(Task<AssetPackStates> task) {
            AssetPackStates assetPackStates;
            try {
                assetPackStates = task.getResult();
                AssetPackState assetPackState =
                    assetPackStates.packStates().get(assetPackName);
            } catch (RuntimeExecutionException e) {
                Log.d("MainActivity", e.getMessage());
                return;
            })


以下 AssetPackState 方法提供了资源包的大小、截至目前已下载的数据量(如已请求),以及已传输到应用的数据量:


  • totalBytesToDownload()

  • bytesDownloaded()

  • transferProgressPercentage()


       如需获取资源包的状态,请使用 status() 方法,该方法以整数形式返回与 AssetPackStatus 类中某个常量字段相对应的状态。尚未安装的资源包状态为 AssetPackStatus.NOT_INSTALLED。


      如果请求失败,请使用 errorCode() 方法,该方法的返回值与 AssetPackErrorCode 类中的某个常量字段相对应。


安装


使用 fetch() 方法首次下载资源包,或要求进行资源包更新以完成操作:

Task<AssetPackStates> fetch(List<String> packNames)


       此方法会返回一个 AssetPackStates 对象,其中包含资源包列表及其初始下载状态和大小。如果通过 fetch() 请求的 Asset Pack 已经在下载,就会返回下载状态,并且不会启动其他下载。


      注意:在大多数情况下,你需要实现 listener 以跟踪下载和安装过程,如下一部分所述。


监控下载状态


       你应实现 listener 以跟踪 Asset Pack 的安装进度。状态更新按 Asset Pack 细分,以支持跟踪各 Asset Pack 的状态。在请求的所有其他下载完成之前,你就可以开始使用已可供使用的资源包。


  • void registerListener(AssetPackStateUpdatedListener listener)


  • void unregisterListener(AssetPackStateUpdatedListener listener)


      注意: 在用户安装或更新应用后,Play 商店会自动触发下载任何 fast-follow 资源包。不过,这些资源包可能无法立即供用户使用。你必须在每次应用启动时检查 fast-follow Asset Pack 的状态。如果下载正在进行,请使用监听器对其进行监控。如果下载已取消或暂停,你可以使用 fetch() 方法恢复下载,如安装部分所述。


下载内容较大


       如果下载内。超过150MB并且用户未连接到 WLAN,那么在用户明确同意使用移动网络连接继续下载前,下载不会开始。同样,如果下载内容较大并且用户与 WLAN 的连接断开,下载会暂停,需要用户明确同意才能使用移动网络连接继续下载。已暂停的 Asset Pack 状态为 WAITING_FOR_WIFI。如需触发界面流程以提示用户同意,请使用 showCellularDataConfirmation() 方法。


      请注意,如果应用不调用此方法,下载会暂停,并且只有当用户重新连接到 WLAN 时才会自动恢复下载。


以下是监听器的一个实现示例:


assetPackStateUpdateListener = new AssetPackStateUpdateListener() {
    @Override
    public void onStateUpdate(AssetPackState assetPackState) {
      switch (assetPackState.status()) {
        case AssetPackStatus.PENDING:
          Log.i(TAG, "Pending");
          break;
        case AssetPackStatus.DOWNLOADING:
          long downloaded = assetPackState.bytesDownloaded();
          long totalSize = assetPackState.totalBytesToDownload();
          double percent = 100.0 * downloaded / totalSize;
          Log.i(TAG, "PercentDone=" + String.format("%.2f", percent));
          break;
        case AssetPackStatus.TRANSFERRING:
          // 100% downloaded and assets are being transferred.
          // Notify user to wait until transfer is complete.
          break;
        case AssetPackStatus.COMPLETED:
          // Asset pack is ready to use. Start the game.
          break;
        case AssetPackStatus.FAILED:
          // Request failed. Notify user.
          Log.e(TAG, assetPackState.errorCode());
          break;
        case AssetPackStatus.CANCELED:
          // Request canceled. Notify user.
          break;
        case AssetPackStatus.WAITING_FOR_WIFI:
          if (!waitForWifiConfirmationShown) {
            assetPackManager.showCellularDataConfirmation(MainActivity.this)
              .addOnSuccessListener(new OnSuccessListener<Integer> () {
                @Override
                public void onSuccess(Integer resultCode) {
                  if (resultCode == RESULT_OK) {
                    Log.d(TAG, "Confirmation dialog has been accepted.");
                  } else if (resultCode == RESULT_CANCELED) {
                    Log.d(TAG, "Confirmation dialog has been denied by the user.");
                  }
                }
              });
            waitForWifiConfirmationShown = true;
          }
          break;
        case AssetPackStatus.NOT_INSTALLED:
          // Asset pack is not downloaded yet.
          break;
      }
    }
}


 或者,你也可以使用 getPackStates() 方法获取当前下载的状态。AssetPackStates 包含下载进度、下载状态和任何失败的错误代码


获取资源包


       在下载请求达到 COMPLETED 状态后,你可以使用文件系统调用获取资源包。使用 getPackLocation() 方法获取资源包的根文件夹。


       资源存储于资源包根目录内的 assets 目录下。你可以使用便捷方法 assetsPath() 获取 assets 目录的路径。请使用以下方法获取特定资产的路径:


private String getAbsoluteAssetPath(String assetPack, String relativeAssetPath) {
    AssetPackLocation assetPackPath = assetPackManager.getPackLocation(assetPack);
    if (assetPackPath == null) {
        // asset pack is not ready
        return null;
    }
    String assetsFolderPath = assetPackPath.assetsPath();
        // equivalent to: FilenameUtils.concat(assetPackPath.path(), "assets");
    String assetPath = FilenameUtils.concat(assetsFolderPath, relativeAssetPath);
    return assetPath;
}


取消请求


       使用 cancel() 取消有效的资源包请求。请注意,此请求是尽力而为的操作。

移除资源包


       使用 removePack() 安排移除资源包。


获取多个资源包的位置


       使用 getPackLocations() 批量查询多个资源包的状态,此方法将返回资源包与其位置的映射。getPackLocations() 返回的映射包含当前已下载且为最新状态的每个 Asset Pack 的条目。


相关推荐


Android aab打包


Android App Bundle 已取代 APK

相关文章
|
1月前
|
存储 Java API
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
Java实现导出多个excel表打包到zip文件中,供客户端另存为窗口下载
45 4
|
2月前
|
分布式计算 大数据 Java
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
36 1
大数据-86 Spark 集群 WordCount 用 Scala & Java 调用Spark 编译并打包上传运行 梦开始的地方
|
1月前
|
Java Maven Android开发
【Azure Developer】VS Code打包Java maven Project 遇见 BUILD FAILURE
Unknown lifecycle phase "lean". You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id>[:<plugin-version>]:<goal>
|
2月前
|
Java Maven 数据安全/隐私保护
如何实现Java打包程序的加密代码混淆,避免被反编译?
【10月更文挑战第15天】如何实现Java打包程序的加密代码混淆,避免被反编译?
114 2
|
2月前
|
Java C++
做了个Java打包工具,可以双击启动了!
本文介绍了作者日常使用Java和Swing进行开发的经验,以及Java程序分发时遇到的问题,如需要JRE环境。文中列举了几种常见的Java程序打包方法,并对比了各自的优缺点,最后作者结合这些方案,利用Winform开发了一款工具,将Java程序打包成二进制可执行文件,简化了分发流程。
做了个Java打包工具,可以双击启动了!
|
2月前
|
Java Shell Maven
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
Flink-11 Flink Java 3分钟上手 打包Flink 提交任务至服务器执行 JobSubmit Maven打包Ja配置 maven-shade-plugin
128 4
|
4月前
|
安全 Java Android开发
【Android P】OTA升级包定制,移除不需要更新的分区,重新打包签名
如何解压OTA升级包、编辑升级包内容(例如移除不需要更新的分区)、重新打包、签名以及验证OTA文件的过程。
355 2
【Android P】OTA升级包定制,移除不需要更新的分区,重新打包签名
|
3月前
|
Java Android开发 C++
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
163 1
|
4月前
|
存储 搜索推荐 Java
探索安卓开发中的自定义视图:打造个性化UI组件Java中的异常处理:从基础到高级
【8月更文挑战第29天】在安卓应用的海洋中,一个独特的用户界面(UI)能让应用脱颖而出。自定义视图是实现这一目标的强大工具。本文将通过一个简单的自定义计数器视图示例,展示如何从零开始创建一个具有独特风格和功能的安卓UI组件,并讨论在此过程中涉及的设计原则、性能优化和兼容性问题。准备好让你的应用与众不同了吗?让我们开始吧!
|
4月前
|
Java 调度 Android开发
Android经典实战之Kotlin的delay函数和Java中的Thread.sleep有什么不同?
本文介绍了 Kotlin 中的 `delay` 函数与 Java 中 `Thread.sleep` 方法的区别。两者均可暂停代码执行,但 `delay` 适用于协程,非阻塞且高效;`Thread.sleep` 则阻塞当前线程。理解这些差异有助于提高程序效率与可读性。
85 1