zoukankan      html  css  js  c++  java
  • android: 记录app运行过程中产生的log

    有时在解决问题时,经常需要借助logcat才能分析定位问题,这里写了一个小工具,能够记录app运行期间的log, 这样测试人员在反馈bug时,只需要把logcat发给我们就可以了。具体代码如下:

    import android.content.Context;
    import android.content.Intent;
    import android.net.Uri;
    import android.os.Environment;
    import android.text.TextUtils;
    import android.util.Log;
    
    import java.io.File;
    import java.io.IOException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    /**
     * A tool class is used to capture the logcat generated by the app running.
     * <p>The logcat save path: sdcard/Android/data/packageName/files/Documents/logcatSaveDir</p>
     *
     * @author xp.chen
     */
    public class LogWatcher {
    
        public static final String TAG = LogWatcher.class.getSimpleName();
    
        private static volatile LogWatcher instance = null;
    
        private static final String LOG_FILE_PREFIX = "logcat_";
        private static final String LOG_FILE_SUFFIX = ".txt";
    
        private static String sLogDirPath;
    
        private Context mContext;
    
        private Process mLogcatProcess;
    
        private File mLogcatFile;
    
        private LogWatcher() {}
    
        public static LogWatcher getInstance() {
            if (instance == null) {
                synchronized (LogWatcher.class) {
                    if (instance == null) {
                        instance = new LogWatcher();
                    }
                }
            }
            return instance;
        }
    
        /**
         * Init the logcat watcher.
         *
         * @param context    Application context.
         * @param logDirName Logcat save dir
         * @return LogcatWatcher instance.
         */
        public LogWatcher init(Context context, String logDirName) {
            if (context == null)
                throw new IllegalArgumentException("LogWatcher: init failed, context can not be null");
    
            if (TextUtils.isEmpty(logDirName))
                throw new IllegalArgumentException("LogWatcher: init failed, logDirName can not be null");
    
            this.mContext = context.getApplicationContext();
            if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
                File documentFileDir = mContext.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS);
                if (documentFileDir != null) {
                    sLogDirPath = documentFileDir.getAbsolutePath() + File.separator + logDirName;
                } else {
                    Log.e(TAG, "LogWatcher: init LogWatcher failed!");
                }
            } else {
                sLogDirPath = mContext.getFilesDir().getAbsolutePath() + File.separator + logDirName;
            }
    
            return this;
        }
    
        /**
         * Start capture the logcat generated by the app.
         */
        public void startWatch() {
            stopWatch();
    
            if (TextUtils.isEmpty(sLogDirPath)) {
                Log.e(TAG, "LogWatcher: can not watch log, the log dir can not be created");
                return;
            }
    
            mLogcatFile = createNewLogFile();
            if (mLogcatFile == null) {
                Log.e(TAG, "LogWatcher: can not create new log file");
                return;
            } else {
                Log.i(TAG, "LogWatcher: log file save path >>> " + mLogcatFile.getAbsolutePath());
            }
    
            // Clear cache log
            try {
                Process process = Runtime.getRuntime().exec("logcat -c");
                process.destroy();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            //final String LOGCAT_FILTER_CMD = "logcat -v time *:v | grep "(" + android.os.Process.myPid() + ")" > " + newLogFile.getAbsolutePath();
            final String LOGCAT_FILTER_CMD = "logcat -v time *:V -f " + mLogcatFile.getAbsolutePath();
    
            try {
                mLogcatProcess = Runtime.getRuntime().exec(LOGCAT_FILTER_CMD);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        /**
         * Stop capture the logcat generated by the app.
         */
        public void stopWatch() {
            if (mLogcatProcess != null) {
                mLogcatProcess.destroy();
                mLogcatProcess = null;
            }
    
            if (mLogcatFile != null) {
                notifySystemToScan(mContext, mLogcatFile);
            }
        }
    
        private File createNewLogFile() {
            File logSaveDir = new File(sLogDirPath, getCurrentDateStr());
            if (!logSaveDir.exists()) {
                boolean mkdirs = logSaveDir.mkdirs();
                if (!mkdirs) {
                    Log.e(TAG, "LogWatcher: create new save dir failed");
                    return null;
                }
            }
    
            String logFileName = LOG_FILE_PREFIX + getCurrentTimeStr() + LOG_FILE_SUFFIX;
            File logFile = new File(logSaveDir, logFileName);
    
            try {
                boolean createRet = logFile.createNewFile();
                if (!createRet) {
                    Log.e(TAG, "LogWatcher: create new log file failed");
                    return null;
                }
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            }
    
            return logFile;
        }
    
        private static String getCurrentTimeStr() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.getDefault());
            return sdf.format(new Date(System.currentTimeMillis()));
        }
    
        private static String getCurrentDateStr() {
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault());
            return sdf.format(new Date(System.currentTimeMillis()));
        }
    
        private static void notifySystemToScan(Context context, File file) {
            if (context == null || file == null) return;
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            Uri uri = Uri.fromFile(file);
            intent.setData(uri);
            context.sendBroadcast(intent);
        }
    
    }
    
    

    为了简化使用,我把所有相关的操作都放在一个类里去完成了,这样只需要包含这一个文件即可。notifySystemToScan()的作用是为了在写入完成后能够刷新logcat文件,否则写入完毕后连上电脑在Windows上看不到文件。

    默认保存路径为:Android/data/packageName/files/Documents/Logcat目录下。为了方便查看,在保存时我按照日期创建了不同的文件夹对logcat进行保存。

    主要实现思想利用了adb logcat -f 这个指令,它可以持续不断的向某个文件中写入数据。

    开始记录:

    private void startLogWatcher() {
            LogWatcher.getInstance().init(getApplicationContext(), PathDefine.LOG_SAVE_DIR).startWatch();
        }
    

    停止记录:

    LogWatcher.getInstance().stopWatch();
    

    运行截图:

    (完)

  • 相关阅读:
    MFC Slider控件 去掉边上的虚线
    VC學習網址
    全局程序集缓存工具 (Gacutil.exe)
    滚动条集合
    调用 DialogBox 会失败解决方法
    全局程序集缓存GAC”是什么概念
    UltraVNC:超实用的远程控制工具(图)
    VC程序员之无法选择的命运
    C++类
    角色权限批量设置,随点!
  • 原文地址:https://www.cnblogs.com/yongdaimi/p/13298650.html
Copyright © 2011-2022 走看看