游戏上线,频繁的crash会极大的影响用户的体验,但是没有crash记录就没法更快更好的解决类似的问题。
Unity里有提供一个CrashReport接口,但是目前只能在IOS上使用。
游戏crash后,再次启动,使用CrashReport.lastReport会取得上次crash的信息,之后就可以做相应处理,是文件记录还是上传服务器。
更通用的方法,是考虑一般unity里的crash都是C#抛出了未捕获的异常所引起的,所以在异常抛出时记录并处理,可以解决unity C#部分的相关crash。
Unity的Application提供了logMessageReceived和logMessageReceivedThreaded两个event来回调处理所有unity的log,
根据log的不同类型可以区分是异常或者错误来处理就可以满足处理crash的需求了。这两个event是用来代替原来被废弃的RegisterLogCallback和RegisterLogCallbackThreaded的。
具体实现如下,
using UnityEngine;
using System.IO;
public class CallStack : MonoBehaviour {
private static Object lock_;
private static StreamWriter writer_;
private static void LogCallback(string condition, string stackTrace, LogType type) {
lock (lock_) {
if (type == LogType.Exception || type == LogType.Error) {
writer_.WriteLine(“{0}: {1}\n{2}”, type, condition, stackTrace);
}
}
void Start () {
lock_ = new Object();
writer_ = new StreamWriter(Path.Combine(Application.persistentDataPath, “crashtrack.txt”));
writer_.AutoFlush = true;
Application.logMessageReceived += LogCallback;
}
}
logMessageReceivedThreaded是用来监听当前线程的log回调的,因为我们要监听全部线程,所以用logMessageReceived。
另外,如果在游戏运行过程中想要获取callstack,可以使用StackTrace类来实现,
using System.Diagnostics;
public void Callstack() {
try {
throw new UnityException(“Exception”);
} catch(System.Exception e) {
StackTrace trace = new StackTrace(true);
UnityEngine.Debug.Log(trace.ToString());
}
最后需要注意,类中static成员变量尽量放在Start或者Awake中实例化,
因为GameObject只能在主线程中实例化,而且Application.dataPath一些类也只能在主线程中访问。而在Android中,像UI等功能都会开新的线程来运行。
说到crash,就要提到真机调试了,很多问题只要在固定设备上才能重现,所以真机调试很重要。
Android的真机调试,官方文档说明需要电脑和手机在同一个wifi环境下,
先连接usb,使用adb
adb tcpip 5555
如果不成功,尝试其他端口,如果成功会输出
restarting in TCP mode port: 5555
然后
adb connect DEVICEIPADDRESS
连接你的手机的ip地址,如果成功会输出
connected to DEVICEIPADDRESS:5555
使用
adb devices
查看手机是否连接
List of devices attached
DEVICEIPADDRESS:5555 device
编译运行,确定Development Build和Script Debugging已经打开,
usb可以不需要连接了,
使用vs或者monodeveloper选择Attach to 就可以看到相应机器了。
官方文档
- 本文固定链接: http://www.wy182000.com/2015/08/14/unity-crash-callstack跟踪和设备调试/
- 转载请注明: wy182000 于 Studio 发表