在APP正式环境中对于用户产生的一些问题,不方便判断的异常或者一些实用的定位问题的信息。但是又不能把用户的手机连接到电脑上。尤其是像我们应用的http请求的数据都是加密的,即使通过抓包也无法看到数据格式,这时候多想能看到用户手机输出的log啊。所以我就想能不能通过手机获取控制台的log并显示显示出来呢。要实现这种功能需要准备两个库
1.日志收集的库
https://github.com/ljuns/LogCollector
2.显示浮窗
https://github.com/princekin-f/EasyFloat
有了这两个库我们就可以愉快的开始了:
第一步:开始日志获取
LogCollector.getInstance(application)
.setCleanCache(true)
.setTag("OkHttp")
.start()
第二步:显示浮窗
private fun showFloatWindown() { EasyFloat.with(this)
.setTag("logFloat")
.setShowPattern(ShowPattern.FOREGROUND)
.setMatchParent(widthMatch = true, heightMatch = false)
.setAppFloatAnimator(null)
.setLayout(R.layout.common_float_app_log, OnInvokeView { val rcvLog = it.findViewById<RecyclerView>(R.id.rcvLog) val llConsoler = it.findViewById<LinearLayout>(R.id.llConsoler) val tvClear = it.findViewById<TextView>(R.id.tvClear) tvClear.setOnClickListener { LogCollector.getInstance(application).logChangeObserver.clear() } val logChangeObserver = LogCollector.getInstance(application).logChangeObserver val logAdapter = LogAdapter(logChangeObserver.arrayList as ArrayList<String>) rcvLog.setAdapter(logAdapter) logChangeObserver.addObserver(logAdapter) it.findViewById<View>(R.id.iv_head).setOnClickListener { //如果显示则隐藏,如果隐藏则关闭 if(llConsoler.visibility == View.VISIBLE){ llConsoler.visibility = View.GONE it.setBackgroundColor(Color.TRANSPARENT) }else{ llConsoler.visibility = View.VISIBLE it.setBackgroundColor(getColorRes(R.color.transparent40)) } } })
.show()
}
这样实现就可以直接获取当前控制台已经输出的信息了。并保存到sdcard目录
但是如果我想一直实时获取控制台的信息,并显示到手机页面呢。这时候需要对日志收集库做一些小小的修改。
找到源码中的LogRunnable类,在run方法中添加一个while循环
private class LogRunnable implements Runnable { volatile boolean isCrash = false; @Override public void run() {
while (!isCrash){
List<String> getCommandLine = new ArrayList<>(); createGetCommand(getCommandLine); BufferedReader reader = null; BufferedWriter writer = null; try { createCleanCommand(); // 获取 logcat Process process = Runtime.getRuntime().exec( getCommandLine.toArray(new String[getCommandLine.size()])); reader = new BufferedReader( new InputStreamReader(process.getInputStream(), UTF8));// writer = new BufferedWriter(// new OutputStreamWriter(new FileOutputStream(mCacheFile), UTF8)); String str; while (!isCrash && ((str = reader.readLine()) != null)) { createCleanCommand(); if (filterStringType(str)) { continue; } // 写数据// writer.write(str);// writer.newLine();// writer.flush(); //直接写到内存中 logChangeObserver.addStr(str); } } catch (IOException e) { e.printStackTrace(); } finally { CloseUtils.close(reader); CloseUtils.close(writer);
}
}
}
}
然后通过ArrayList将日志字符串保存到内容中,交给RecyclerView去显示。
这样所有的工作就完成了。