一、前言
UnityGoogle PlayGoogleAPK150MAPK300M+UnitySplit Application Binary
二、Demo工程
DemoResources目录和StreamingAssets目录分别放一张图片。场景如下,
Canvas节点挂Main.cs脚本,image节点显示图片。场景中的
image节点不要引用图片资源,而是在Main.cs脚本中动态赋值。Main.cs脚本代码如下:
using UnityEngine;
using UnityEngine.UI;
public class Main : MonoBehavIoUr {
public Image img;
void Start() {
img.sprite = Resources.Load<Sprite>("bg");
}
}
运行效果如下,可以看到动态加载了图片。
此时我们打包
apk,如果我们不开启Split Application Binary,显然,Resources和StreamingAssets目录都会打进包内。
三、开启Split Application Binary,打包
Player SettingsPublishing SettingsSplit Application Binary执行
Build打包,如下,保存为test.apk。最终生成的文件如下,可以看到有一个
apk和一个obb文件。四、什么文件进入了obb中
obbOpaque Binary Blobapk7zassetsobbapk往里进,看到了
pic2.png,这个就是Unity中StreamingAssets目录中的pic2.png,也就是说,StreamingAssets目录中的文件,会被丢到obb文件中。那
Resources目录的资源,也是在obb中 吗?我们往里进,可以看到在assets\bin\Data目录中有个data.unity3d文件,我猜,我们Resources目录中的那张bg.png就在这里面。我用
AssetStudioGUI.exe无法反出这个data.unity3d文件,那么,我们就用反证法来证明Resources目录文件会在obb文件中吧。
五、只安装apk,不放obb
apkResourcesbg.pngapk现在,另一个问题来了,这个
obb文件,如何使用,放在安卓中的哪个目录呢?
六、放obb文件
obbobbmain..<包名>.obbapkcom.linxinfa.obbtestBundle Version Code2 所以最终
obb重命名如下:main.2.com.linxinfa.obbtest.obb把它拷贝到
Android/obb/包名目录下,如下:七、运行apk闪退
apkadb
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一般是在 https://unity.cn/ 下载,这里下的,都是中国版的。那么,在哪里下载国际版的
Unity呢?
八、下载国际版Unity
Unity
九、国际版发布apk+obb
apk+obb按照同样的规则放好
obb包,apk由此,我们得出结论,
Resources目录的资源也是在obb文件中。
十、您上传的APK没有经过Zipalign处理
apkobbGoogle Console您上传的APK没有经过Zipalign处理,请对APK 运行 Zipalign 工具,然后重新上传
Android 1.6SDKbuild-tools\26.0.2zipalign
zipalign -v 4 源文件 对齐之后的文件
例:
zipalign -v 4 test.apk test_aligned.apk
十一、Google Play Console后台在哪里上传apk、obb
Google ConsoleAPKAPK上传成功后,点击这个...按钮然后选择
上传拓展文件(.obb)然后上传
obb就可以啦。十二、结束语
UnityUnity