Unity3D研究院之IOS&Android收集Log文件

来源:互联网 发布:mysql Delete 与drop 编辑:程序博客网 时间:2024/06/05 10:54

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

[AppleScript] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
<fontface="Verdana,">usingUnityEngine;
usingSystem.Collections;
usingSystem.Collections.Generic;
usingSystem.IO;
usingSystem.Text;
  
publicclassOutLog :MonoBehaviour
{
    static List mLines =new List();
    static List mWriteTxt =new List();
    privatestringoutpath;
    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(stringt intemp)
            {
                using(StreamWriter writer =new StreamWriter(outpath,true,Encoding.UTF8))
                {
                    writer.WriteLine(t);
                }
                mWriteTxt.Remove(t);
            }
        }
    }
  
    void HandleLog(stringlogString,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)
    {
        stringtext = "";
        for(int i =0; i <objs.Length; ++i)
        {
            if(i==0)
            {
                text+=objs.ToString();
            }
            else
            {
                text+=", " + objs.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);
        }
    }
}</font>

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

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

[AppleScript] 纯文本查看 复制代码
?
1
2
3
4
void Start (){
    int []test =new int[1];
    test[2]=0;
}

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


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


        打包之前在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选项而产生对应的路径,如果你还是不知道路径我建议你输出一下它。

补充

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

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


0 0