溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

logcat日志在網(wǎng)頁上的實時輸出(環(huán)形日志緩沖區(qū)的實現(xiàn))

發(fā)布時間:2020-06-21 21:48:56 來源:網(wǎng)絡(luò) 閱讀:4145 作者:心如明鏡 欄目:開發(fā)技術(shù)

    android手機(jī)上的logcat會不斷的打印出日志。我們想要實現(xiàn)這樣一個目標(biāo):在網(wǎng)頁上顯示某個手機(jī)的logcat打印信息,就像這樣:

logcat日志在網(wǎng)頁上的實時輸出(環(huán)形日志緩沖區(qū)的實現(xiàn))

因為是logcat是動態(tài)實時不斷打印的,所以,不論多大的緩存都會被撐爆。所以,必須使用環(huán)形緩沖區(qū),覆蓋和重用日志緩沖區(qū)。如果日志打印過快,顯然會出現(xiàn)新舊日志堆疊的問題。但常規(guī)情形下,使用環(huán)形日志緩沖區(qū),都能收到比較好的實測效果。

接收日志的裝置(里邊放置環(huán)形緩沖容器logs,是一個列表,環(huán)形是通過放置邏輯實現(xiàn)的):

  1. public final class GetLogReceiver extends MultiLineReceiver { 
  2.      
  3.     // 五和:環(huán)形緩沖區(qū)的容量大小 
  4.     private static final int MAX_LOG_COUNT = 3000
  5.      
  6.     private List<String> logs; 
  7.      
  8.     private int writePos = 0
  9.      
  10.     public GetLogReceiver() { 
  11.         // 環(huán)形日志容器,留一條日志為空作為結(jié)束位置標(biāo)識 
  12.         logs = new ArrayList<String>(MAX_LOG_COUNT); 
  13.          
  14.         for(int i=0; i<MAX_LOG_COUNT; i++) { 
  15.             logs.add(null); 
  16.         } 
  17.     } 
  18.  
  19.     @Override 
  20.     public boolean isCancelled() { 
  21.         return false
  22.     } 
  23.  
  24.     @Override 
  25.     public void processNewLines(String[] lines) { 
  26.         synchronized(logs) { 
  27.  
  28.             for(String line : lines) { 
  29.                 if(!line.trim().equals("")) { 
  30.                     logs.set(writePos, line); 
  31.                     writePos++; 
  32.                     writePos = writePos % MAX_LOG_COUNT; 
  33.                 } 
  34.             } 
  35.              
  36.             logs.set(writePos, null); 
  37.         } 
  38.     } 
  39.  
  40.     public List<String> getNextBatchLogs(int start, int count) { 
  41.         List<String> result = new ArrayList<String>(); 
  42.          
  43.         synchronized(logs) { 
  44.             int firstReadPos = start % MAX_LOG_COUNT; 
  45.              
  46.             for(int i=0; i<count; i++) { 
  47.                 readPos = (firstReadPos + i)%MAX_LOG_COUNT; 
  48.                 if (logs.get(readPos) != null) { 
  49.                     result.add(logs.get(readPos)); 
  50.                 } else { 
  51.                     break
  52.                 } 
  53.             } 
  54.         } 
  55.          
  56.         return result; 
  57.     } 

getNextBatchLogs提供了2個參數(shù),一個是start,一個是count,前者表示網(wǎng)頁開始讀取日志的位置,后者表示網(wǎng)頁想要讀取日志的條數(shù)。通過這兩個參數(shù),網(wǎng)頁可以通過ajax前向獲取日志內(nèi)容。

運行l(wèi)ogcat的線程(核心代碼):

  1. public void run() { 
  2.             while(true) { 
  3.                 try { 
  4.                     String serialNumber = device.getSerialNumber(); 
  5.                     String runLogcatCmd = "logcat -v time"
  6.                     device.executeShellCommand(runLogcatCmd, 
  7.                             LogReceiverManager.getInstance().getLogReceiver(serialNumber)); 
  8.                 } catch (TimeoutException e) { 
  9.                     e.printStackTrace(); 
  10.                 } catch (AdbCommandRejectedException e) { 
  11.                     // 五和:表明手機(jī)被拔掉了 
  12.                     break
  13.                 } catch (IOException e) { 
  14.                     // 五和:adb不穩(wěn)定會拋此異常 
  15.                     break
  16.                 } catch (ShellCommandUnresponsiveException e) { 
  17.                     e.printStackTrace(); 
  18.                 } 
  19.                  
  20.                 // 每間隔1秒重試一次 
  21.                 try { 
  22.                     Thread.sleep(1000); 
  23.                 } catch (InterruptedException e) { 
  24.                     e.printStackTrace(); 
  25.                 } 
  26.                  
  27.                 if (isKilled) { 
  28.                     break
  29.                 } 
  30.             } 
  31.         } 

這里,通過LogReceiverManager給每個手機(jī)維護(hù)一個日志緩存裝置,通過serialNumber可以獲取到GetLogReceiver對象。

原理很簡單,實現(xiàn)還是有點精巧的,因為代碼并不多,效果比較好。此logcat實時打印的功能,百度的MTC貌似現(xiàn)在還未提供。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI