概述
前言
最近遇到一个应用闪退问题,在某些机型和mumu模拟器上会出现,而其他机型和模拟器都是正常的,从Unity代码层面并没有发现问题,只能利用安卓调试看看了
工具
首先需要的工具:
- DDMS:查看安卓日志
- ADB:连接手机/模拟器调试
直接去官网下载SDK,需要的工具都在里面。Android SDK下载
安装好之后如图所示:根目录;ADB;DDMS
系统配置好环境变量,Path: E:/AndroidSDK/platform-tools
,方便adb调试
tools中的ddms.bat
和monitor.bat
都是查看工具,只不过monitor.bat
的版本比较新一点
开始调试
闪退的应用是在mumu模拟器上发生的,先打开模拟器
双击打开monitor.bat
,功能很多,我们暂时只用Log Cat
此时Device中未显示任何设备
-
模拟器需要手动连接,不同模拟器连接不同端口
网易mumu模拟器端口号:7555 夜神模拟器 端口号 :62001 海马玩模拟器 端口号:26944 天天模拟器 端口号:6555
Windows+R, 打开命令行cmd
执行 adb connect 127.0.0.1:7555
连接成功
-
安卓真机则需要在手机中打开USB调试,输入
adb devices
可查看已连接设备
此时已连上模拟器,可查看到相关进程的日志,自定义过滤器查看我们需要的日志
从反复的闪退中查到以下日志信息
- 读取本地assetbundle资源失败,无法打开文件
- Too many opened files
搜索了一下“too many opened files”,原因是进程可打开的句柄数量有限制,对于不同机型不同设备不同,所以这就是为什么只有部分机型闪退了
目前只知道打开文件的数量过多,句柄实例化过多,内存泄露导致无法读取资源文件,要具体定位到是哪个文件还需要进一步调试
Linux操作指令
查看当前所有进程: ps
查看当前句柄总数:adbshell lsof -p <pid> |wc –l
查看当前句柄详情:adb shell lsof -p <pid>
-
从DDMS中可以获取当前启动Unity应用的pid,或者通过ps指令找到进程的pid :1241
-
查看当前句柄总数,
adbshell lsof -p <pid> | wc –l
看到当前进程加载的句柄是1378个
-
查看句柄详情,
adb shell lsof -p <pid>
看到加载的文件清单
-
映入眼帘的是一大片加载的字体
选中一个字体进行过滤lsof -p <pid> | grep xxx
,发现同一个字体加载了很多次mem:memory-mapped file, 已加载到内存中 124r: r:表示该文件被打开并处于只读模式 211r ... 954r
-
于是又开了一个正常的应用来对比,看到正常的时候字体只加载了一次
-
看来闪退的原因找到了,字体文件加载过多,导致进程开启了很多实例句柄,超过了数量限制
为什么会加载如此多的字体文件, 从lsof的结果上又看了看
发现加载assetbundle文件的时候,都会又加载一次字体
那么问题找到了
字体文件没有设置assetbundle!
字体文件没有设置assetbundle!
字体文件没有设置assetbundle!
-
由于项目使用的是NGUI,最近新导入了一种字体,大部分界面使用了这种字体,而且字体还没有设置assetbundle,在打包资源的时候,每一个用到该字体的ab包里,都会包含一份字体文件
所以每次加载有关资源,都会加载一遍字体,实例化了大量文件句柄,导致了异常 -
如果对字体设置了assetbundle,那么打包资源的时候,会对该字体单独生成一份ab资源,其他ab包里只会包含对该资源的引用,而不是包含完整的内容,从而避免资源冗余
总结
资源打包的时候,重复利用的公共资源需要单独设置assetbundle,从而避免资源冗余,减少包大小
例如:公共图集,字体,公共组件等
最后
以上就是跳跃酒窝为你收集整理的Unity安卓应用闪退-使用DDMS工具查看安卓日志/ADB真机调试的全部内容,希望文章能够帮你解决Unity安卓应用闪退-使用DDMS工具查看安卓日志/ADB真机调试所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复