文章目录
一、前言
点关注不迷路,持续输出Unity
干货文章。
嗨,大家好,我是新发。
最近项目上架Google Play
,因为Google
限制上传的APK
不得超过150M
,而实际项目APK
有300M+
,这个时候,就需要用到Unity
的Split Application Binary
功能了。
二、Demo工程
为了演示,我弄个Demo
工程,如下:
Resources
目录和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
目录都会打进包内。
关于
Resources
和StreamingAssets
两个目录的区别,可以参见我之前写的这篇文章:《学Unity的猫》——第五章:规范Unity的工程目录结构
三、开启Split Application Binary,打包
在Player Settings
的Publishing Settings
中开启Split Application Binary
。
执行
Build
打包,如下,保存为test.apk
。最终生成的文件如下,可以看到有一个
apk
和一个obb
文件。四、什么文件进入了obb中
obb
全称是Opaque Binary Blob
,它是apk
的扩展文件,它是压缩文件的格式,以zip格式居多,所以我们可以直接用7z
打开它,我们看看里面有什么。
进去里面是一个assets
文件夹,从这里看,我们就可以知道obb
主要是存放apk
的资源和数据类文件了。
往里进,看到了
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
我们把apk
安装到安卓模拟器中,运行如下,可以看到,不能动态加载出图片来,说明,Resources
目录的bg.png
并不在apk
中。
现在,另一个问题来了,这个
obb
文件,如何使用,放在安卓中的哪个目录呢?
六、放obb文件
要使用这个obb
文件,需要先重命名一下这个obb
文件,命名规则如下:main.<Bundle Version Code>.<包名>.obb
我打包apk
时,包名是com.linxinfa.obbtest
,Bundle Version Code
是2
。
所以最终
obb
重命名如下:main.2.com.linxinfa.obbtest.obb
把它拷贝到
Android/obb/包名
目录下,如下:七、运行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
一般是在 https://unity.cn/ 下载,这里下的,都是中国版的。那么,在哪里下载国际版的
Unity
呢?
八、下载国际版Unity
国际版Unity
官网:https://unity.com/ (需要科学上网)
九、国际版发布apk+obb
最终,使用国际版打出了apk+obb
包,
按照同样的规则放好
obb
包,运行apk
,可以看到运行正常了。
由此,我们得出结论,
Resources
目录的资源也是在obb
文件中。
十、您上传的APK没有经过Zipalign处理
上传apk
和obb
包到Google Console
时,提示您上传的APK没有经过Zipalign处理,请对APK 运行 Zipalign 工具,然后重新上传
。
原因:
Google官网介绍:
我们强烈推荐在新的和已经发布的程序上使用zipalign工具来得到优化后的版本——即使你的程序是在老版本的Android平台下开发的。在你的应用程序上运行zipalign,使得在运行时Android与应用程序间的交互更加有效率。因此,这种方式能够让应用程序和整个系统运行得更快。Android SDK中包含一个“zipalign”的工具,它能够对打包的应用程序进行优化。
Android 1.6
及以后的SDK
的 build-tools\26.0.2
都有zipalign
工具。你可以使用它来对齐任何版本下的程序包。
对齐命令如下:
zipalign -v 4 源文件 对齐之后的文件
例:
zipalign -v 4 test.apk test_aligned.apk
十一、Google Play Console后台在哪里上传apk、obb
首先登录Google Console
:https://play.google.com/console/u/0/developers/
先上传你的APK
,
APK
上传成功后,点击这个...
按钮然后选择
上传拓展文件(.obb)
然后上传
obb
就可以啦。@H_959_502@
十二、结束语
完毕。
喜欢Unity
的同学,不要忘记点击关注,如果有什么Unity
相关的技术难题,也欢迎留言或私信~
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。