10

Unity3D研究院之IOS&Android收集Log文件(六十二)

 3 years ago
source link: https://www.xuanyusong.com/archives/2477
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Unity3D研究院之IOS&Android收集Log文件(六十二)

有段时间没有写过文章了,不知道大伙儿还记得雨松MOMO吗? 嘿嘿。

开发项目的时候尤其在处理与服务器交互这块,如果服务端程序看不到客户端请求的Log信息,那么无法修改BUG。在Windows上Unity会自动讲Log文件写入本地,但是在IOS和Android上确没有这个功能,所以我想了个办法,把Log信息写在手机的客户端里。把如下脚本挂在任意游戏对象上即可。

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
public class OutLog : MonoBehaviour
static List<string> mLines = new List<string>();
static List<string> mWriteTxt = new List<string>();
private string outpath;
void Start () {
//Application.persistentDataPath Unity中只有这个路径是既可以读也可以写的。
outpath = Application.persistentDataPath + "/outLog.txt";
//每次启动客户端删除之前保存的Log
if (System.IO.File.Exists (outpath)) {
File.Delete (outpath);
//在这里做一个Log的监听
Application.RegisterLogCallback(HandleLog);
//一个输出
Debug.Log("xuanyusong");
void Update ()
//因为写入文件的操作必须在主线程中完成,所以在Update中哦给你写入文件。
if(mWriteTxt.Count > 0)
string[] temp = mWriteTxt.ToArray();
foreach(string t in temp)
using(StreamWriter writer = new StreamWriter(outpath, true, Encoding.UTF8))
writer.WriteLine(t);
mWriteTxt.Remove(t);
void HandleLog(string logString, string stackTrace, LogType type)
mWriteTxt.Add(logString);
if (type == LogType.Error || type == LogType.Exception)
Log(logString);
Log(stackTrace);
  //这里我把错误的信息保存起来,用来输出在手机屏幕上
static public void Log (params object[] objs)
string text = "";
for (int i = 0; i < objs.Length; ++i)
if (i == 0)
text += objs[i].ToString();
text += ", " + objs[i].ToString();
if (Application.isPlaying)
if (mLines.Count > 20)
mLines.RemoveAt(0);
mLines.Add(text);
void OnGUI()
GUI.color = Color.red;
for (int i = 0, imax = mLines.Count; i < imax; ++i)
GUILayout.Label(mLines[i]);

如果在Mac上,可以借助同步推类似的工具来把你的Log文件取出来。

Unity3D研究院之IOS&Android收集Log文件(六十二) - 雨松MOMO程序研究院 - 1

Android上取法类似。

此时如果客户端报错了怎么办?如果你是在IOS平台,强烈建议把PlayerSetting里面的Script Call Optimization设置成Slow and Safe,这样比如遇到空指针 或者 数组越界这样的错误,程序是不会直接闪退的。(Android上不用设置)这里我创造一个数组越界的错误。

void Start () {
int []test = new int[1];
test[2] = 0;

 那么在手机上报错以后,会自动将错误信息的堆栈打印在屏幕上。前提一定要设置Script Call Optimization设置成Slow and Safe,不然就直接闪退了。

补充,我看有朋友在下面给我留言问我安卓Android上面无法取出Log文件,今天在详细说明一下。

Unity3D研究院之IOS&Android收集Log文件(六十二) - 雨松MOMO程序研究院 - 3

打包之前在Android的Player Setting里面选择WriteAccess (写入访问)

Internal Only:表示Application.persistentDataPath的路径是应用程序沙盒,(需要root不然访问不了写入的文件)

文件路径:data/data/包名/Files/OutLog.txt

External(SDCard):表示Application.persistentDataPath的路径是SDCard的路径。(不需要root就可以访问文件)

文件路径:SDCard/Android/包名/Files/OutLog.txt

后者你可以利用 腾讯 360 百度 91  各种手机助手把文件取出来。(建议使用后者)

总结 Application.persistentDataPath 会根据你的WriteAccess选项而产生对应的路径,如果你还是不知道路径我建议你输出一下它。

6月11日补充 

项目中我一直用Application.RegisterLogCallback(HandleLog);方法来记录手机iOS和Android下产生的Log。结果今天测试小妹告诉我她在手机里面取出的LOG不全(LOG记录在本地后可以通过同步推一类的软件把LOG取出来)

经过仔细研究后发现原来最近我接了一个sdk,它在后台也用Application.RegisterLogCallback(HandleLog)来监听Log,我的程序是先执行我的RegisterLogCallback 然后在执行它的RegisterLogCallback所以它就把我的RegisterLogCallback覆盖了,那么我在HandleLog就监听不到了,即使有LOG产生也不会进我的方法了。。 解决的办法就是保证项目中只有一个Application.RegisterLogCallback(HandleLog)即可。


作者:雨松MOMO
专注移动互联网,Unity3D游戏开发
捐 赠写博客不易,如果您想请我喝一杯星巴克的话?就进来看吧!

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK