logcat日志是Android开发调试的必备手段,由于开发人员水平不均关系,遇到滥用logcat的项目也不在少数。相信大家在开发调试中遇到不少应用即使是发布版本也有超级多的log信息,非常烦人,用处也不大,甚至自己参与的项目内部不同模块之间存在部分模块滥用logcat的情况。对于logcat信息的理解与开发人员的水平和开发观念有非常大关系,本人认为滥用logcat是不好的开发习惯。近期参与的项目就遇到这种情况,部分模块存在滥用logcat的情况。
首先介绍项目的具体情况,最近接收一个项目,项目也不是很大出去引用的第三方开源代码就五万行java代码左右,项目大概是14年开发的,虽然整体架构问题不是很大,但是开发的人多了,加上中间有些人员变动,代码质量有所下降,会出现一些腐朽代码。这次接手要添加几个大的需求修改,需要协调原来的开发人员。在debug模式下apk的Log.d信息特别多,release版本因为proguard脚本会删除Log.d等级日志,所以整体好一点,可是Log.d的日志本来就是开发调试用的,功能开发完成后其实用处不大了,可以删除的。
项目新需求启动前还有一个空窗期,决定利用这个空窗期解决这个问题。先创建一个封装了 Log.d的日志工具类,该工具类打印 的日志能够显示java类名称调用函数的名称以及代码行号;然后就使用文本替换把项目中的Log.d替换为我写的工具类;接下来就是苦力活,运行apk,这时候对应的Log.d都会打印出源码位置,最后根据实际日志的作用适当减少冗余日志。
初步搞定完原来日志后,新项目开始后就对协同开发的同事声明新开发模块的日志要求,不能再打印冗余日志,管理小技巧是git或者svn版本控制工具追踪冗余PLog.d对应的代码,然后找相关同事更正,经过半个月的适应后协同开发的同事终于不会在功能开发完成的模块打印调试冗余日志了。
PLog的实现大概如下:
package com.penny.demo; import android.text.TextUtils; import android.util.Log; import java.util.Locale; /** * Created by penny on 06/02/2018. */ public class PLog { public static void d(String tag, String log) { boolean reachPLog = false; StackTraceElement element = null; StackTraceElement[] elements = Thread.currentThread().getStackTrace(); for (int i = 0; i < elements.length; i++) { element = elements[i]; if (! reachPLog) { reachPLog = TextUtils.equals(PLog.class.getName(), element.getClassName()); } else { if (! TextUtils.equals(PLog.class.getName(), element.getClassName())) { break; } } } if (null == log) { log = "null"; } String finalLog = String.format(Locale.CHINA, "%s::%s(%d) %s", parseSimpleName(element.getClassName()), element.getMethodName(), element.getLineNumber(), log); Log.d(tag, finalLog); } /** * reserve $ */ private static String parseSimpleName(String className) { if (TextUtils.isEmpty(className)) { return ""; } int index = className.lastIndexOf("."); if (-1 == index) { return className; } return className.substring(index + 1); } }
单元测试用例
package com.penny.demo; import android.support.test.runner.AndroidJUnit4; import org.junit.Test; import org.junit.runner.RunWith; /** * Created by penny on 06/02/2018. */ @RunWith(AndroidJUnit4.class) public class PLogTest { private static final String TAG = PLogTest.class.getSimpleName(); @Test public void testPLog() { PLog.d(TAG, "Hello, word."); } @Test public void testNestClassLog() { Game game = new Game("The Travelling frog"); game.dump(); } private class Game { private String name; public Game(String name) { this.name= name; } public void dump() { PLog.d(TAG, "name: " + this.name); } } }
测试用例运行结果
$ adb logcat -s "PLogTest"
02-06 23:39:40.454 11099 11120 D PLogTest: PLogTest::testPLog(18) Hello, word.
02-06 23:39:40.475 11099 11120 D PLogTest: PLogTest$Game::dump(35) name: The Travelling frog
做这个项目的感慨:一个项目的编码整洁规范程度与主持项目实施的人相关,如果实施人注重编码规范,那么项目整体会规范。反之亦然,主持人不注重规范,再好的框架也会慢慢被随意编码污染。我处理的这个项目原来的框架挺优秀的,简洁明了,模块之间耦合性低,所以才能抵住部分人员短时间不规范编码。