離線抓取並保存Android Logcat的工具

在工作中,會碰到一些設備上的原因,導致不能一直連着數據線抓logcat,這個時候需要一個能夠離線抓取logcat的工具,有些芯片廠商提供的rom版本中自帶這個工具,例如MTK的MTKLogger、高通的logcatuserdebug版本),這些工具都能夠自動抓取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以及系統簽名

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章