在工作中,會碰到一些設備上的原因,導致不能一直連着數據線抓logcat,這個時候需要一個能夠離線抓取logcat的工具,有些芯片廠商提供的rom版本中自帶這個工具,例如MTK的MTKLogger、高通的logcat(userdebug版本),這些工具都能夠自動抓取logcat的內容
提示,製作抓取系統log的工具,需要將應用系統簽名,否則只能拿到本應用的log
圍繞抓取log過程中,產生了兩個思路,但是思路一沒有走通,如果想要直接使用的,請看思路二
思路一:logcat重定向,我們知道平時看logcat一般是在Android Studio中的界面中帶工具可以查看,不過我們也可以在cmd中執行
adb logcat -v time > log.txt
這樣就把logcat輸出定向到了log.txt文件,不過這是在adb環境下通過連線輸出到電腦上的重定向,跟機器本身的重定向不同,那麼機器本身的重定向是怎麼做的呢,我們進入到shell後執行下面的命令,其中&符號是linux中後臺運行的命令
adb shell
logcat -v time > /sdcard/log.txt &
實際測試可以用,但是存在問題,重啓後就又失效了,而我們有時候抓取log的時候就是爲了抓啓動界面的日誌
所以我們需要一個apk執行這個命令,讓apk在開機自啓運行這段命令,有人會問那不是隻能抓到這個apk啓動之後的log麼,其實logcat工具本身帶有一些緩存,這也是我們有時候在調試應用的時候,出了問題之後再連上數據線也能看到出錯日誌的原因,所以利用這一點,再加上Runtime這個類,在apk中執行這段命令
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("logcat -v time > /sdcard/log.txt &");
但是這個時候我們就遇到了一個坑,Runtime.exec()不是命令解析器這段代碼不會被執行,後面查了資料就有了思路二,我們自己讀取logcat內容,自己寫文件,而不是通過重定向讓系統幫忙寫,看來是不能省力了,還是要自己做
思路二:讀取logcat中的內容,寫入文件
如何直接讀取logcat中的內容呢,使用下面的方法,使用這個代碼的效果有點像在終端中輸入命令cmd,結果會顯示在終端中,不過這個不會顯示在終端裏面,需要我們自己讀取裏面的內容
ProcessBuilder processBuilder = new ProcessBuilder(new String[]{"sh", "-c", cmd});
processBuilder.redirectErrorStream(true);
先對processBuilder初始化,cmd中傳入需要執行的命令
這裏我們的cmd爲
String cmd = "logcat -v time";
初始化之後,獲取Process對象
try {
process = processBuilder.start();
new ReadThread(process.getInputStream(), "InputStream").start();
new ReadThread(process.getErrorStream(), "ErrorStream").start();
} catch (IOException e) {
e.printStackTrace();
}
讀取線程我是這樣寫的
class ReadThread extends Thread {
InputStream inputStream;
int flag = OUTPUT;
String name = "None Name";
public ReadThread(InputStream inputStream, String name) {
this.inputStream = inputStream;
this.name = name;
}
@Override
public void run() {
super.run();
try {
byte[] buffer = new byte[1024 * 8];
int length = 0;
while (true) {
while ((length = inputStream.read(buffer)) != -1) {
byte[] tmp = new byte[length];
System.arraycopy(buffer, 0, tmp, 0, length);
Message message = handler.obtainMessage();
message.what = flag;
message.obj = new String(tmp);
handler.sendMessage(message);
buffer = new byte[1024 * 8];
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
這就是讀取logcat內容並寫入文件的過程,做成app後還有很多工作,例如需要請求存儲權限、開機自啓、空間滿了之後怎麼處理、如何設定log大小循環寫入等等等,這個屬於業務上的內容了,就不另外擴展了
還有一點需要注意的是,需要設置systemuid以及系統簽名