前言
年前有个想法,过去后端调试接口的时候,需要对接网络请求的各个参数,每次要调试时的流程都是(对于Android客户端的我来说):
打开Android Studio → 连接设备或模拟器 → 开启logcat → 日志筛选 ......
这样确实有点麻烦,有没有一种方式把网络请求和返回的日志全部打到Demo App里边显示?
答案当然是有!
上个demo图:
由于涉及公司接口的安全性,这里就不把具体的代码实现罗列出来了。。涉及的技术点不多,这边就重新做了个有点趣味性的答题demo:
逻辑很简单:点击“问题”按钮 → 打印日志 → 发送日志 → 筛选日志 → 更新UI(TextView)
此demo下载地址
简单介绍logcat
通过 Log 类,你可以创建日志消息,这些消息会显示在 logcat 中。一般来说,你应使用以下日志方法,这些方法按照优先级从高到低(或者从最简略到最详细)的顺序列示:
- Log.e(String, String) Error (错误:显示已经引发错误的问题,以及此列表中较低的消息级别)
- Log.w(String, String Warn (警告:显示尚不是错误的潜在问题,以及此列表中较低的消息级别)
- Log.i(String, String) Info (信息:显示常规使用情况的预期日志消息,以及此列表中较低的消息级别)
- Log.d(String, String) Debug (调试:显示仅在开发期间有用的调试日志消息,以及此列表中较低的消息级别)
- Log.v(String, String) Verbose (详细:显示所有日志消息(默认值))
功能实现
以下代码实现的是点击按钮,然后捕获输出日志的过程:
findViewById(R.id.log1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 1.输出日志
Log.e(TAG, ANSWER1);
new Thread() { // 2. 开启线程来捕获日志
@Override
public void run() {
Process mLogcatProc = null;
BufferedReader reader = null;
try {
mLogcatProc = Runtime.getRuntime().exec(new String[]{"logcat", "TextLogDemoTag:E *:S"});
reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
//logcat打印信息在这里可以监听到
Message msg3 = new Message();
Bundle bundle = new Bundle();
msg3.what = 0x11;
// 使用looper 把给界面一个显示
if (line.contains(ANSWER1)) {
bundle.putString("answer", line);
msg3.setData(bundle);
// 3. 发送日志通知主线程更新UI
mHandler.sendMessage(msg3);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}.start();
}
});
··· ···
final Handler mHandler = new Handler() {
@SuppressLint("SetTextI18n")
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 0x11) {
Bundle bundle = msg.getData();
String answer = bundle.getString("answer");
if (answer != null) {
// 截取输出字符串:“03-25 11:02:53.411 4423-4423/demo.hzmd.com.textlogdemo E/TextLogDemoTag: 问题10答案:10次”
String final_ans = answer.substring(answer.indexOf(":") + 1, answer.length());
//更新UI
show_log.setText(final_ans);
process.setText(final_ans);
} else {
show_log.setText("无答案");
process.setText("无答案");
}
}
}
};
··· ···
观察一下可以知道,代码的逻辑主要分为四个部分:
- 首先通过
Log.e(TAG, ANSWER1)
输出日志到系统,日志级别我们设置为E - 通过开启一个新的线程来捕获日志
- 通知主线程来更新UI:这里指的是刷新TextView的内容
- 主线程获取到数据,筛选截取有用的内容并更新UI
其中,关键是在于Runtime.getRuntime().exec(new String[]{"logcat", "TextLogDemoTag:E *:S"})
这个方法。
Runtime.getRuntime().exec(String cmdarray[])方法主要用于执行外部的程序或命令,方法传入的是一个数组对象,包含所调用命令及其参数的数组。在代码中参数的含义是:
- "logcat" 就是我们主要的logcat命令
- "TextLogDemoTag" 表示监听的Tag 这里以上面点击按钮输出的LOG信息为例。
- "E"表示监听的Log类型,当然这里还可以写其它类型 。VERBOSE(v) 、DEBUG(d)、 INFO(i)、 WARN(w)、 ERROR(e), 不过须要与监听的与Tag一一对称才可以。
- "*:s"表示监听所有的信息,这里表示只要tag是TextLogDemoTag,Logcat类型为E 的 所有Log都会被获取到。
TextLogDemoTag:E *:S
这是一套规则,当然方法允许多个规则,你也可以添加多几个规则作为参数。
注意
最后记得在AndroidManifest.xml中中添加权限:
<uses-permission android:name="android.permission.READ_LOGS" />
我在demo代码中忘记了加,当然你如果把手机调为debug模式也可以不用加。。。。把?
参考文档:
在Android界面上显示和获取Logcat日志输出
Android开发之在程序中时时获取logcat日志信息的方法
android 捕捉实时logcat日志 并且显示在textview中