美文网首页Utils通用类Android开发
打造不一样的android log日志类

打造不一样的android log日志类

作者: androidman | 来源:发表于2017-09-17 01:01 被阅读214次
    image.png
    • 有这么一个场景

    万恶的测试人员,总是爱找我们的茬,每次一出问题就拿手机过来,尼玛,什么东西麻,一堆bug,还让不让人下班。然后呢没办法啰,测试就是上帝,你就只好拿他的手机过来找日志啰,尼玛,日志出来一大堆,还要滚到最后才能看到最新的错误信息,这时间也浪费得够可以的了。。。百万只草泥马飘过。。。还有一大堆bug要修复呢,年纪轻轻的,我还不想被拉去祭天,怎么办。。。
    duang...duang... 这个log日志神器就这样出天上掉下来了。。。
    可以设置每个log的文件大小有木有。。。
    可以格式化输出漂亮的样式的log有木有。。。
    可以把最新的错误信息在文件最前面显示有木有。。。
    足不出户就可以在内网上查看手机上面的log有木有。。。
    真的是神器,有木有。。。
    现在已躺在github有木有。。。
    欢迎收看我的博客有木有。。。
    欢迎使用 FastAndrUtils android快速开发工具类有木有。。。

    广告买多了。。。不好意思。。。现在进入正题

    • 功能列表

    1. 可设置Log的开启和关闭
    2. 可自定义Log的Tag
    3. 可设置log保存的文件大小
    4. 可设置是否保存log到sd卡
    5. log以html格式保存,且带html样式,查看更直观方便
    6. 可显示当前log的包名,类名,及行号,可点击行号跳转
    7. log保存可以实现头部数据插入,显示最新的log在最前面查看log更方便
    8. log带边框输出,查看更直观
    9. 可内网通过浏览器查看log数据
    • 有图有真相

    log带边框输出 内网查看log列表 内网log内容查看
    • 功能实现

    由于code不少,就不贴完整代码,就找些关键的来写。完整代码可到github观看。

    • log的基本配置
     /**
         * 是否开启bebug模式
         */
        public FLogUtils debug(boolean debug) {
          ...
        }
    
        /**
         * 是否保存到sd卡
         */
        public FLogUtils saveSD(boolean savesd) {
          ...
        }
    
        /**
         * 设置log文件大小
         */
        public FLogUtils setLogSize(int logSize) {
         ...
        }
    
        /**
         * 设置log文件目录
         */
        public FLogUtils setlogDir(String logDir) {
          ...
        }
    
    • log日志输出
    //默认tag日志输出
     public void e(String msg) {
            e("www.hotapk.cn", msg);
        }
    //自定义日志输出
     public void e(String tag, String msg) {
         ...
        }
    
    
    • 获取log的当前所在的类及行数
    private String targetStackTraceMSg() {
            StackTraceElement targetStackTraceElement = getTargetStackTraceElement();
            if (targetStackTraceElement != null) {
                return "at " + targetStackTraceElement.getClassName() + "." + targetStackTraceElement.getMethodName() +
                        "(" + targetStackTraceElement.getFileName() + ":" + targetStackTraceElement.getLineNumber() + ")";
    
            } else {
                return "";
            }
        }
    
        private StackTraceElement getTargetStackTraceElement() {
            StackTraceElement targetStackTrace = null;
            boolean shouldTrace = false;
            StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    
            for (StackTraceElement stackTraceElement : stackTrace) {
                boolean isLogMethod = stackTraceElement.getClassName().equals(FLogUtils.class.getName());
                if (shouldTrace && !isLogMethod) {
                    targetStackTrace = stackTraceElement;
                    break;
                }
                shouldTrace = isLogMethod;
            }
            return targetStackTrace;
        }
    
    
    • log保存到sd卡
     /**
         * 追加数据
         *
         * @param filePath
         * @param content
         * @param header   是否在头部追加数据
         */
        public static void appendText(String filePath, String content, boolean header) {
            RandomAccessFile raf = null;
            FileOutputStream tmpOut = null;
            FileInputStream tmpIn = null;
            try {
                File tmp = File.createTempFile("tmp", null);
                tmp.deleteOnExit();//在JVM退出时删除
    
                raf = new RandomAccessFile(filePath, "rw");
                //创建一个临时文件夹来保存插入点后的数据
                tmpOut = new FileOutputStream(tmp);
                tmpIn = new FileInputStream(tmp);
                long fileLength = 0;
                if (!header) {
                    fileLength = raf.length();
                }
                raf.seek(fileLength);
                /**将插入点后的内容读入临时文件夹**/
    
                byte[] buff = new byte[1024];
                //用于保存临时读取的字节数
                int hasRead = 0;
                //循环读取插入点后的内容
                while ((hasRead = raf.read(buff)) > 0) {
                    // 将读取的数据写入临时文件中
                    tmpOut.write(buff, 0, hasRead);
                }
                //插入需要指定添加的数据
                raf.seek(fileLength);//返回原来的插入处
                //追加需要追加的内容
                raf.write(content.getBytes());
                //最后追加临时文件中的内容
                while ((hasRead = tmpIn.read(buff)) > 0) {
                    raf.write(buff, 0, hasRead);
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (tmpOut!=null){
                    try {
                        tmpOut.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if (tmpIn!=null){
                    try {
                        tmpIn.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (raf!=null){
                    try {
                        raf.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    

    以上就是实现了基本自定义的log的造轮子功能
    以下内容才是我这log工具类的关键。。。

    让你的log日志可以在内网访问

    1. 使用鼎鼎有名的 nanohttpd 类 ,这样就可以把android当内网服务器来使用了
    • 继承NanoHTTPD类
    public class LogNetServer extends NanoHTTPD {
        private Context context;
    
        public LogNetServer(int port) {
            super(port);
        }
    
        public LogNetServer(String hostname, int port) {
            super(hostname, port);
        }
    
        public LogNetServer(int port, Context context) {
            super(port);
            this.context = context;
        }
    
    
        @Override
        public Response serve(IHTTPSession session) {
            String file_name = session.getUri().substring(1);
            StringBuffer br = new StringBuffer();
            String header = FAssetsARawUtils.getAssetsToString("baidu.html", context);
            br.append(header);
            String filedir = FLogUtils.getInstance().getLogFileDir();
            FLogUtils.getInstance().e("测试下效果-----");
            if (file_name.isEmpty()) {
                File[] files = FFileUtils.getFiles(filedir);
                if (files != null) {
                    for (int i = 0; i < files.length; i++) {
                        br.append(
                                "<div class=\"exp\"><a href = "
                                        + "/log?logfile="
                                        + files[i].getName() +
                                        " target=\"_blank\" >" + files[i].getName() +
                                        "</a ></div>"
                        );
                    }
    
                }
            } else {
                Map<String, String> parms = session.getParms();
                if (parms.containsKey("logfile")) {
                    String name = parms.get("logfile");
                    String logstr = FFileUtils.readFile(filedir + "/" + name);
                    br.append(logstr);
                } else {
                    br.append("有问题");
                }
    
            }
            br.append("</body></html>");
    
            return newFixedLengthResponse(Response.Status.OK, "text/html", br.toString());
        }
    }
    
    • FLogUtils 创建启动和关闭WebServer服务方法
    /**
         * 启动log的WebServer服务
         *
         * @param port
         * @param context
         */
        public void startLogServer(int port, Context context) {
            if (testHttpd == null) {
                synchronized (FLogUtils.class) {
                    if (testHttpd == null) {
                        testHttpd = new LogNetServer(port, context.getApplicationContext());
                    }
                }
            }
            try {
                testHttpd.start();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
     /**
         * 关闭log的WebServer服务
         */
        public void stopLogServer() {
            if (testHttpd != null && testHttpd.isAlive()) {
                testHttpd.stop();
            }
        }
    
    
    • 还有一个html文件
    <!Doctype html>
    <html xmlns=http://www.w3.org/1999/xhtml>
    <head>
        <meta http-equiv=Content-Type content="text/html;charset=utf-8">
        <title>less code , less bug</title>
    
        <style type="text/css">
    .dotted {border-style: dotted;
    margin-top: 36px;}
    .exp{ border-bottom:1px dashed #F00}
    div {padding: 10px;}
    .redcolor{ color:#F00;}
        </style>
    
    </head>
    <body>
    

    啰嗦了半天终于写完了这篇log工具类的文章,文采不好,莫见怪。。。
    看完整代码请移步github

    相关文章

      网友评论

      本文标题:打造不一样的android log日志类

      本文链接:https://www.haomeiwen.com/subject/lozysxtx.html