赞
踩
1.简介
在Android APP Bundle(aab)之前,上架Google Play 项目都是打包成APK上传,但是Google 对 APK大小是有限制的,刚开始是50M,后来扩展到100M,但是有些APK资源比较多,可能会大于100M, 基于这种情况,Google 允许上传一个额外的扩展文件,这个文件就是咱们今天要详解的.obb文件。每当您使用 Google Play 管理中心上传 APK 时,您都可以选择向 APK 添加一个或两个扩展文件。每个文件的大小上限为 2 GB,文件格式可以是您选择的任意格式。不过,为了节约下载时的带宽,我们建议您使用压缩格式的文件。从概念上讲,每个扩展文件扮演着不同的角色:
尽管您可以按照您需要的方式使用这两个扩展文件,但我们建议您按如下方式使用:主扩展文件提供主要的资源,尽量不要更新;补丁扩展文件应该比较小,用作“补丁载体”,在每次发布重要版本时或根据需要进行更新。
不过,即使应用更新只需要新的补丁扩展文件,您仍然必须上传新的 APK 并在清单中更新 versionCode。(Play 管理中心不允许您将扩展文件上传到现有 APK 中。)
2.生成.obb
一般我们会把APP中一些大的资源,或者升级用的APK,先打包成一个zip, 比如名字为:MYOBB.zip 然后再对打包成的ZIP重命名成: main.versionCode.包名.obb 比如: main.22070479.cool.obb.android.obb
3.随着APK 一块把obb文件上传到Google Play Console:
打开Google Console后台,找到对应的项目: https://play.google.com/console/u/0/developers
上传APK
上传完APK后 有个更多 点击更多,选择上传扩展文件(.obb)
就这样把APK和obb文件一块上传到Google Play,内测用户就可以下载安装了,等测试的没问题就可以发布到正式线上环境了,当用户下载该APK时,我们上传的obb文件也会同步下载到手机中
4.下载APK的同时下载对应的obb文件
下载APK后 ,之前上传的obb文件也会同步下载下来,当 Google Play 将扩展文件下载到设备时,会将其保存到系统的共享存储位置。为确保应用的正常运行,请勿删除、移动或重命名扩展文件。如果您的应用必须自行从 Google Play 进行下载,那么您必须将文件保存到相同的位置。
下载下来后存放的位置:
根目录:getExternalStorageDirectory() + /Android/obb/<package-name>/XXX.obb
例如:
String obb_filename = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/obb/" + getPackageName() + "/main.22070479.cool.obb.android.obb";
这个时候打开APP后就开始解压使用obb文件了
5.解压并使用OBB中的文件:
首先APP要有读写权限才能对obb文件操作:
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
拿到读写权限后开始解压obb:
- public void unZipObb(String srcFilePath, String dstFolderPath) {
- Log.d("MainActivity", "unZipObb : srcFilePath=" + srcFilePath + ", dstFolderPath=" + dstFolderPath);
- try {
- String obbFilePath = srcFilePath;
- if (obbFilePath == null) {
- Log.d("MainActivity", "unZipObb error : obbFilePath == null");
- return;
- } else {
- File obbFile = new File(obbFilePath);
- if (!obbFile.exists()) {
- //下载obb文件
- Log.d("MainActivity", "unZipObb error : !obbFile.exists()");
- } else {
- File outputFolder = new File(dstFolderPath);
- if (!outputFolder.exists()) {
- //目录未创建 没有解压过
- outputFolder.mkdirs();
- unZip(obbFile, outputFolder.getAbsolutePath());
- } else {
- //目录已创建 判断是否解压过
- if (outputFolder.listFiles() == null) {
- //解压过的文件被删除
- unZip(obbFile, outputFolder.getAbsolutePath());
- } else {
- //此处可添加文件对比逻辑
- Log.d("MainActivity", "unZipObb error : outputFolder.listFiles() != null");
- }
- }
- }
- }
- } catch (Exception e) {
- Log.d("MainActivity", "unZipObb error : Exception");
- e.printStackTrace();
- }
- }
-
- public void createDirectoryIfNeeded(String folderPath) {
- File folder = new File(folderPath);
- if (!folder.exists() || !folder.isDirectory()) {
- folder.mkdirs();
- }
- }
-
- public void unZip(File zipFile, String outPathString) {
- Log.d("MainActivity", "unZip " + zipFile.getName() + " to " + outPathString);
- try {
- createDirectoryIfNeeded(outPathString);
- ZipInputStream inZip = new ZipInputStream(new FileInputStream(zipFile));
- ZipEntry zipEntry;
- String szName;
- while ((zipEntry = inZip.getNextEntry()) != null) {
- szName = zipEntry.getName();
- if (zipEntry.isDirectory()) {
- szName = szName.substring(0, szName.length() - 1);
- File folder = new File(outPathString + File.separator + szName);
- folder.mkdirs();
- } else {
- File file = new File(outPathString + File.separator + szName);
- createDirectoryIfNeeded(file.getParent());
- file.createNewFile();
- FileOutputStream out = new FileOutputStream(file);
- int len;
- byte[] buffer = new byte[1024];
- while ((len = inZip.read(buffer)) != -1) {
- out.write(buffer, 0, len);
- out.flush();
- }
- out.close();
- }
- }
- inZip.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
6.拿到OBB中的文件,就可以使用解压出来的文件了:
- String srcPNG1 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/11.png";
- String srcPNG2 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/12.png";
- String srcPNG3 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/13.png";
- String srcPNG4 = Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhOOB/MYOBB/14.png";
-
- mChangeBTN.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
-
- int position = mCount % 4;
- switch (position) {
- case 0:
- Glide.with(MainActivity.this).load(srcPNG1).into(mShowImageView);
- break;
- case 1:
- Glide.with(MainActivity.this).load(srcPNG2).into(mShowImageView);
- break;
- case 2:
- Glide.with(MainActivity.this).load(srcPNG3).into(mShowImageView);
- break;
- case 3:
- Glide.with(MainActivity.this).load(srcPNG4).into(mShowImageView);
- break;
- }
- mCount++;
-
- }
- });
总结:详细介绍了OBB的整个生命周期,从生成OBB----->上传Google Play ---->用户下载同步OBB ----->解压OBB ----->使用OBB中的文件
参考文档:https://developer.android.com/google/play/expansion-files#Overview
OBB Demo GitHub : https://github.com/JasonZhangHG/OBBDemo.git
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。