Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)

文章目录

      • 一、前言
      • 二、Demo工程
      • 三、开启Split Application Binary,打包
      • 四、什么文件进入了obb中
      • 五、只安装apk,不放obb
      • 六、放obb文件
      • 七、运行apk闪退
      • 八、下载国际版Unity
      • 九、国际版发布apk+obb
      • 十、结束语

一、前言

点关注不迷路,持续输出Unity干货文章。
嗨,大家好,我是新发。
最近项目上架Google Play,因为Google限制上传的APK不得超过150M,而实际项目APK300M+,这个时候,就需要用到UnitySplit Application Binary功能了。

二、Demo工程

为了演示,我弄个Demo工程,如下:
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第1张图片
Resources目录和StreamingAssets目录分别放一张图片。
场景如下,Canvas节点挂Main.cs脚本,image节点显示图片。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第2张图片
场景中的image节点不要引用图片资源,而是在Main.cs脚本中动态赋值。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第3张图片
Main.cs脚本代码如下:

using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour {
     
    public Image img;
    void Start() {
     
        img.sprite = Resources.Load<Sprite>("bg");
    }
}

运行效果如下,可以看到动态加载了图片。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第4张图片
此时我们打包apk,如果我们不开启Split Application Binary,显然,ResourcesStreamingAssets目录都会打进包内。

关于ResourcesStreamingAssets两个目录的区别,可以参见我之前写的这篇文章:《学Unity的猫》——第五章:规范Unity的工程目录结构

三、开启Split Application Binary,打包

Player SettingsPublishing Settings中开启Split Application Binary
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第5张图片
执行Build打包,如下,保存为test.apk
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第6张图片
最终生成的文件如下,可以看到有一个apk和一个obb文件。
在这里插入图片描述

四、什么文件进入了obb中

obb全称是Opaque Binary Blob,它是apk的扩展文件,它是压缩文件的格式,以zip格式居多,所以我们可以直接用7z打开它,我们看看里面有什么。
进去里面是一个assets文件夹,从这里看,我们就可以知道obb主要是存放apk的资源和数据类文件了。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第7张图片
往里进,看到了pic2.png,这个就是UnityStreamingAssets目录中的pic2.png,也就是说,StreamingAssets目录中的文件,会被丢到obb文件中。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第8张图片
Resources目录的资源,也是在obb中 吗?我们往里进,可以看到在assets\bin\Data目录中有个data.unity3d文件,我猜,我们Resources目录中的那张bg.png就在这里面。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第9张图片
我用AssetStudioGUI.exe无法反出这个data.unity3d文件,那么,我们就用反证法来证明Resources目录文件会在obb文件中吧。

五、只安装apk,不放obb

我们把apk安装到安卓模拟器中,运行如下,可以看到,不能动态加载出图片来,说明,Resources目录的bg.png并不在apk中。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第10张图片
现在,另一个问题来了,这个obb文件,如何使用,放在安卓中的哪个目录呢?

六、放obb文件

要使用这个obb文件,需要先重命名一下这个obb文件,命名规则如下:main..<包名>.obb
我打包apk时,包名是com.linxinfa.obbtestBundle Version Code2
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第11张图片
所以最终obb重命名如下:main.2.com.linxinfa.obbtest.obb
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第12张图片
把它拷贝到Android/obb/包名目录下,如下:
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第13张图片

七、运行apk闪退

接着,我们运行apk,发现闪退了,为什么?
adb调试一下,日志如下:

D/Activity( 6326): on create, cpu abi: armeabi-v7a, brand: Android
D/updatePackage(  905): version com.linxinfa.obbtest 2
I/Launcher(  905): Deferring update until onResume
V/libnb   ( 6326): enter native_bridge2_isSupported /data/app/com.linxinfa.obbtest-1/lib/arm/libmain.so
D/libnb   ( 6326): enter native_bridge2_loadLibrary /data/app/com.linxinfa.obbtest-1/lib/arm/libmain.so
D/com.netease.nemu_vapi_android.thread.HttpServer(  842): http server response data: {"errcode":0,"message":"OK"}
D/houdini ( 6326): [6326] Added shared library /system/lib/arm/libaudio_rawdata.so for ClassLoader by Native Bridge.
D/houdini ( 6326): [6326] Added shared library /data/app/com.linxinfa.obbtest-1/lib/arm/libmain.so for ClassLoader by Native Bridge.
V/libnb   ( 6326): enter native_bridge2_getTrampoline JNI_OnLoad
D/com.netease.nemu_vapi_android.thread.HttpServer(  842): http server response data: {"errcode":0,"message":"OK"}
I/Mono    ( 6326): JNI_OnLoad called
D/com.netease.nemu_android_watchdog_lib.core.Watchdog(  842): upload server response: {"errcode": 100, "errmsg": "ok"}
D/com.netease.nemu_android_watchdog_lib.core.Watchdog(  842): upload result: true
D/        ( 6326): QemuPipeStream get vt: 1
D/        ( 6326): QemuPipeStream use_vt: 1
D/        ( 6326): HostConnection::get() New Host Connection established 0xbf269540, tid 6326 host arch 0
I/ActivityManager(  523): Displayed com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity: +285ms
W/InputMethodManagerService(  523): Starting input on non-focused client com.android.internal.view.IInputMethodClient$Stub$Proxy@17cc531 (uid=10015 pid=3699)
I/Unity   ( 6326): MemoryManager: Using 'Dynamic Heap' Allocator.
I/Unity   ( 6326): check apk path fail, reported:/storage/emulated/0/Android/obb/com.linxinfa.obbtest/main.2.com.linxinfa.obbtest.obb, actual:/data/app/com.linxinfa.obbtest-1/base.apk
I/Unity   ( 6326):
I/Unity   ( 6326): Illegal usage of unity detected, shutdown unity.
I/Unity   ( 6326):
I/Process ( 6326): Sending signal. PID: 6326 SIG: 9
W/InputDispatcher(  523): channel 'aede570 com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity (server)' ~ Consumer closed input channel or an error occurred.  events=0x9
E/InputDispatcher(  523): channel 'aede570 com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity (server)' ~ Channel is unrecoverably broken and will be disposed!
I/WindowState(  523): WIN DEATH: Window{aede570 u0 com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity}
W/InputDispatcher(  523): Attempted to unregister already unregistered input channel 'aede570 com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity (server)'
W/WindowManager(  523): Force-removing child win Window{8bc567a u0 SurfaceView} from container Window{aede570 u0 com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity}
I/ActivityManager(  523): Process com.linxinfa.obbtest (pid 6326) has died
D/ActivityManager(  523): cleanUpApplicationRecord -- 6326
W/ActivityManager(  523): Force removing ActivityRecord{50e4779 u0 com.linxinfa.obbtest/com.unity3d.player.UnityPlayerActivity t547}: app died, no saved state
W/WindowManager(  523): Failed looking up window
W/WindowManager(  523): java.lang.IllegalArgumentException: Requested window android.os.BinderProxy@7d300e9 does not exist
W/WindowManager(  523):      at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:8881)
W/WindowManager(  523):      at com.android.server.wm.WindowManagerService.windowForClientLocked(WindowManagerService.java:8872)
W/WindowManager(  523):      at com.android.server.wm.WindowState$DeathRecipient.binderDied(WindowState.java:1216)
W/WindowManager(  523):      at android.os.BinderProxy.sendDeathNotice(Binder.java:558)
I/WindowState(  523): WIN DEATH: null
I/com.android.server.tabs.TabManagerService(  523): notifyClosing:741: notify tab closed in android as it's closed task com.linxinfa.obbtest, taskId: 547, elapseTime: 372
D/Interception(  523): result: allow, reason: calleePkg is system app, rule: runType===broadcast|||callerPkg===android|||calleePkg===com.mumu.acc|||calleeClass===com.mumu.acc.AccMsgReceiver|||action===uu.intent.action.STOP_ACCELERATE

在同事的提醒下,看到有一句关键的日志:

Illegal usage of unity detected, shutdown unity.

搜索了一下,原来如此:
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第14张图片
我们在国内下载Unity一般是在 https://unity.cn/ 下载,这里下的,都是中国版的。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第15张图片
那么,在哪里下载国际版的Unity呢?

八、下载国际版Unity

国际版Unity官网:https://unity.com/ (需要科学上网)
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第16张图片

九、国际版发布apk+obb

最终,使用国际版打出了apk+obb包,
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第17张图片
按照同样的规则放好obb包,
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第18张图片

运行apk,可以看到运行正常了。
Unity开启Split Application Binary,打出apk+obb分包,如何进行安装测试(Google、Unity国际版)_第19张图片
由此,我们得出结论,Resources目录的资源也是在obb文件中。

十、结束语

完毕。
喜欢Unity的同学,不要忘记点击关注,如果有什么Unity相关的技术难题,也欢迎留言或私信~

你可能感兴趣的:(Unity3D,unity,Google,obb,apk,分包)