logcat日志在网页上的实时输出(环形日志缓冲区的实现)
android手机上的logcat会不断的打印出日志。我们想要实现这样一个目标:在网页上显示某个手机的logcat打印信息,就像这样:
因为是logcat是动态实时不断打印的,所以,不论多大的缓存都会被撑爆。所以,必须使用环形缓冲区,覆盖和重用日志缓冲区。如果日志打印过快,显然会出现新旧日志堆叠的问题。但常规情形下,使用环形日志缓冲区,都能收到比较好的实测效果。
接收日志的装置(里边放置环形缓冲容器logs,是一个列表,环形是通过放置逻辑实现的):
publicfinalclassGetLogReceiverextendsMultiLineReceiver{//五和:环形缓冲区的容量大小privatestaticfinalintMAX_LOG_COUNT=3000;privateList<String>logs;privateintwritePos=0;publicGetLogReceiver(){//环形日志容器,留一条日志为空作为结束位置标识logs=newArrayList<String>(MAX_LOG_COUNT);for(inti=0;i<MAX_LOG_COUNT;i++){logs.add(null);}}@OverridepublicbooleanisCancelled(){returnfalse;}@OverridepublicvoidprocessNewLines(String[]lines){synchronized(logs){for(Stringline:lines){if(!line.trim().equals("")){logs.set(writePos,line);writePos++;writePos=writePos%MAX_LOG_COUNT;}}logs.set(writePos,null);}}publicList<String>getNextBatchLogs(intstart,intcount){List<String>result=newArrayList<String>();synchronized(logs){intfirstReadPos =start%MAX_LOG_COUNT;for(inti=0;i<count;i++){readPos=(firstReadPos +i)%MAX_LOG_COUNT;if(logs.get(readPos)!=null){result.add(logs.get(readPos));}else{break;}}}returnresult;}}
getNextBatchLogs提供了2个参数,一个是start,一个是count,前者表示网页开始读取日志的位置,后者表示网页想要读取日志的条数。通过这两个参数,网页可以通过ajax前向获取日志内容。
运行logcat的线程(核心代码):
publicvoidrun(){while(true){try{StringserialNumber=device.getSerialNumber();StringrunLogcatCmd="logcat-vtime";device.executeShellCommand(runLogcatCmd,LogReceiverManager.getInstance().getLogReceiver(serialNumber));}catch(TimeoutExceptione){e.printStackTrace();}catch(AdbCommandRejectedExceptione){//五和:表明手机被拔掉了break;}catch(IOExceptione){//五和:adb不稳定会抛此异常break;}catch(ShellCommandUnresponsiveExceptione){e.printStackTrace();}//每间隔1秒重试一次try{Thread.sleep(1000);}catch(InterruptedExceptione){e.printStackTrace();}if(isKilled){break;}}}
这里,通过LogReceiverManager给每个手机维护一个日志缓存装置,通过serialNumber可以获取到GetLogReceiver对象。
原理很简单,实现还是有点精巧的,因为代码并不多,效果比较好。此logcat实时打印的功能,百度的MTC貌似现在还未提供。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。