1. 程式人生 > >Android除錯偶現bug的方法

Android除錯偶現bug的方法

在除錯app時,經常出現偶現bug,十分難以除錯,但bug出現時,我們往往來不及獲取log來進行分析。

以下程式碼的功能就是當這些bug出現時,記錄下當時的log。

    /**
     * 
     * @param isError   判斷條件
     * @param activity
     * @param logFileName  log檔案的名字, 該log檔案會出現在當前app的files/中,即  /data/data/com.test.demo/files/ 中
     * @Function
     * @TODO TODO
     */
    public static void checkAndSavaLog(boolean isError, final Activity activity,
            final String logFileName) {
        if (isError) {
            saveLogAsFile(activity, logFileName);
        }
    }


    private static void saveLogAsFile(final Activity activity, final String logFileName) {
        Runnable networkTask = new Runnable() {

            @Override
            public void run() {
                // TODO
                try {
                    ArrayList<String> cmdLine = new ArrayList<String>();
                    cmdLine.add("logcat");
                    cmdLine.add("-d");

                    ArrayList<String> clearLog = new ArrayList<String>();
                    clearLog.add("logcat");
                    clearLog.add("-c");

                    Process process = Runtime.getRuntime()
                            .exec(cmdLine.toArray(new String[cmdLine.size()]));
                    BufferedReader bufferedReader = new BufferedReader(
                            new InputStreamReader(process.getInputStream()));

                    StringBuffer sb = new StringBuffer();
                    String str = null;
                    while ((str = bufferedReader.readLine()) != null) {
                        sb.append(str);
                        sb.append(System.getProperty("line.separator"));
                    }

                    Runtime.getRuntime().exec(clearLog.toArray(new String[clearLog.size()]));

                    if (sb.toString().isEmpty()) {
                        Log.e(TAG, "Why? do not get the log!");
                    }

                    writeFileData(activity.getApplication(), logFileName, sb.toString());

                }
                catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(networkTask).start();
    }

以上程式碼中用到了一些讀寫檔案的方法,程式碼如下:

 private static void initContext(Application application) {
        Context context = application;
        try {
            mContext = context.createPackageContext(context.getPackageName(), Context.CONTEXT_INCLUDE_CODE);
        } catch (NameNotFoundException e) {
            throw new RuntimeException(e);
        }
    }
   /**
     * 
     * @param application
     * @param fileName
     * @param message
     * @Function  write message as a file to the path of The App.  eg. /data/data/com.test.demo/files/
     * @TODO TODO
     */
    public static void writeFileData(Application application, String fileName, String message) {

        initContext(application);
        try {

            FileOutputStream fout = mContext.openFileOutput(fileName, Context.MODE_PRIVATE);
            byte[] bytes = message.getBytes();
            fout.write(bytes);
            fout.close();

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

使用方法,例如我們發現,同一個客戶端傳到伺服器的userid會莫名其妙的變成另外一個userid,那麼就可以在傳送userid的地方寫下

checkAndSavaLog(userid.equals(userid_before), this, "error.log");
這樣當userid傳送的跟之前的不一樣的時候,就會記錄下log資訊供以分析。

本功能只是供開發者在除錯的時候用,如果想要在釋出包中也使用這個功能,就需要加上上傳log檔案的功能了。

關於上傳log檔案:

  1. 如果只是針對一些特定的bug,想要除錯,log檔案不是很多的情況下,那麼就可以借用第三方cdn之類的服務,把log檔案上傳到cdn,然後開發者去分析
  2. 如果希望獲取一些遊戲資料,供以統計分析運營,那麼最好還是自己寫服務端。而且如果不是有特殊需要,比如資料極為私密重要等等,其他情況下,完全可以使用第三方的資料統計工具,比如talkingdata,activation等等