• LogcatHelperDemo【应用log信息保存成本地文件】


    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    简单记录下LogcatHelper的使用,并对原有代码进行了修改【因为保存到应用内的目录中不需要申请权限,所以去掉保存到SD的功能--个人觉得这个类主要用于开发者自己调试用】:

        /**初始化目录 "包名+logcat"
         * */
        public void init(Context context) {
    //        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
    //            PATH_LOGCAT = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + context.getPackageName() + File.separator + "logcat";
    //        } else {
                //如果SD卡不存在,就保存到本应用的目录下【why 直接保存到本应用的目录下】
                PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + File.separator + "logcat";
    //        }
            File file = new File(PATH_LOGCAT);
            if (!file.exists()) {
                file.mkdirs();
            }
        }

    效果图

    存储在应用内的目录:

    logcat-2018-08-14.log 

    2018-08-14 10:18:06  I/art     (24242): Late-enabling -Xcheck:jni
    2018-08-14 10:18:06  W/art     (24242): Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
    2018-08-14 10:18:06  E/Process (24242): android_os_Process_getProcessNameByPid pid is 24242
    2018-08-14 10:18:06  E/Process (24242): android_os_Process_getProcessNameByPid value is ogcathelperdemo
    2018-08-14 10:18:06  V/MainActivity(24242): 这是V日志
    2018-08-14 10:18:06  D/MainActivity(24242): 这是D日志
    2018-08-14 10:18:06  I/MainActivity(24242): 这是I日志
    2018-08-14 10:18:06  W/MainActivity(24242): 这是W日志
    2018-08-14 10:18:06  E/MainActivity(24242): 这是E日志
    2018-08-14 10:18:06  V/PhoneWindow(24242): DecorView setVisiblity: visibility = 4 ,Parent =null, this =com.android.internal.policy.impl.PhoneWindow$DecorView{34498aa9 I.E..... R.....ID 0,0-0,0}
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): Dumper init 4 threads <0x7f84d321c0>
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): <com.why.project.logcathelperdemo> is running.
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): <com.why.project.logcathelperdemo> setHwuiLog: debug.egl.trace=false
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): initialize DisplayEventReceiver 0x7f8ac1a400
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): Use EGL_SWAP_BEHAVIOR_PRESERVED: true
    2018-08-14 10:18:06  D/Atlas   (24242): Validating map...
    2018-08-14 10:18:06  D/ViewRootImpl(24242): hardware acceleration is enabled, this = ViewRoot{296d9189 com.why.project.logcathelperdemo/com.why.project.logcathelperdemo.MainActivity,ident = 0}
    2018-08-14 10:18:06  V/PhoneWindow(24242): DecorView setVisiblity: visibility = 0 ,Parent =ViewRoot{296d9189 com.why.project.logcathelperdemo/com.why.project.logcathelperdemo.MainActivity,ident = 0}, this =com.android.internal.policy.impl.PhoneWindow$DecorView{34498aa9 V.E..... R.....ID 0,0-0,0}
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): CanvasContext() 0x7f8ac1db40 initialize 0x7f91e3c610
    2018-08-14 10:18:06  D/MALI    (24242): eglInitialize:1479: [+]
    2018-08-14 10:18:06  E/GED     (24242): Failed to get GED Log Buf, err(0)
    2018-08-14 10:18:06  D/MALI    (24242): eglInitialize:1850: [-]
    2018-08-14 10:18:06  I/        (24242): elapse(include ctx switch):3533 (ms), eglInitialize
    2018-08-14 10:18:06  I/OpenGLRenderer(24242): Initialized EGL, version 1.4
    2018-08-14 10:18:06  D/MALI    (24242): eglCreateContext:206: [MALI] eglCreateContext display 0x7f91c5fd00, share context 0x0 here.
    2018-08-14 10:18:06  D/MALI    (24242): gles_context_new:248: Create GLES ctx 0x7f8ae8a008 successfully
    2018-08-14 10:18:06  D/MALI    (24242): eglCreateContext:543: [MALI] eglCreateContext end. Created context 0x7f8ae7ad80 here.
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): Created EGL context (0x7f8ae37040)
    2018-08-14 10:18:06  I/OpenGLRenderer(24242): Get enable program binary service property (1)
    2018-08-14 10:18:06  I/OpenGLRenderer(24242): Initializing program atlas...
    2018-08-14 10:18:06  D/ProgramBinary/Service(24242): BpProgramBinaryService.getFileDescriptor
    2018-08-14 10:18:06  D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramMapLen
    2018-08-14 10:18:06  D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramMapArray
    2018-08-14 10:18:06  D/ProgramBinary/Service(24242): BpProgramBinaryService.getProgramBinaryLen
    2018-08-14 10:18:06  I/OpenGLRenderer(24242): Program binary detail: Binary length is 169984, program map length is 152.
    2018-08-14 10:18:06  I/OpenGLRenderer(24242): Succeeded to mmap program binaries. File descriptor is 46, and path is /dev/ashmem{.
    2018-08-14 10:18:06  I/OpenGLRenderer(24242): No need to use file discriptor anymore, close fd(46).
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): TaskManager() 0x7f8acff1f0, cpu = 8, thread = 4
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): Initializing program cache from 0x0, size = -1
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): Enabling debug mode 0
    2018-08-14 10:18:06  D/Surface (24242): Surface::connect(this=0x7f91e3c600,api=1)
    2018-08-14 10:18:06  D/mali_winsys(24242): new_window_surface returns 0x3000
    2018-08-14 10:18:06  D/Surface (24242): Surface::allocateBuffers(this=0x7f91e3c600)
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): [TaskMgr] Running thread hwuiTask1 (24290)
    2018-08-14 10:18:06  W/MALI    (24242): glDrawArrays:714: [MALI] glDrawArrays takes more than 5ms here. Total elapse time(us): 6667
    2018-08-14 10:18:06  D/OpenGLRenderer(24242): ProgramCache save to disk, size = 3
    2018-08-14 10:18:06  V/InputMethodManager(24242): onWindowFocus: null softInputMode=288 first=true flags=#81810100
    2018-08-14 10:18:06  V/InputMethodManager(24242): START INPUT: com.android.internal.policy.impl.PhoneWindow$DecorView{34498aa9 V.E..... R....... 0,0-1080,1920} ic=null tba=android.view.inputmethod.EditorInfo@2ce154f2 controlFlags=#104
    2018-08-14 10:18:06  D/InputMethodManager(24242): receive service's setActive call, active:true
    2018-08-14 10:18:06  I/InputMethodManager(24242): handleMessage: MSG_SET_ACTIVE true, was false

    使用步骤

    一、项目组织结构图

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    (1)将logcathelper包复制到项目中

    package com.why.project.logcathelperdemo.logcathelper;
    
    import android.content.Context;
    
    import java.io.BufferedReader;
    import java.io.File;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;
    
    /**
     * Created by HaiyuKing
     * Used log日志统计保存到本地文件
     * 参考资料 Android将应用log信息保存文件:http://www.cnblogs.com/weixing/p/3414164.html
     */
    public class LogcatHelper {
        private static LogcatHelper INSTANCE = null;
        /**日志文件保存路径*/
        private static String PATH_LOGCAT;
        private LogDumper mLogDumper = null;
        /**应用进程ID*/
        private int mPId;
    
        /**初始化目录 "包名+logcat"
         * */
        public void init(Context context) {
    //        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {// 优先保存到SD卡中
    //            PATH_LOGCAT = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + context.getPackageName() + File.separator + "logcat";
    //        } else {
                //如果SD卡不存在,就保存到本应用的目录下【why 直接保存到本应用的目录下】
                PATH_LOGCAT = context.getFilesDir().getAbsolutePath() + File.separator + "logcat";
    //        }
            File file = new File(PATH_LOGCAT);
            if (!file.exists()) {
                file.mkdirs();
            }
        }
        /**单例模式
         * */
        public static LogcatHelper getInstance(Context context) {
            if (INSTANCE == null) {
                INSTANCE = new LogcatHelper(context);
            }
            return INSTANCE;
        }
    
        private LogcatHelper(Context context) {
            init(context);
            mPId = android.os.Process.myPid();
        }
    
        public void start() {
            if (mLogDumper == null)
                mLogDumper = new LogDumper(String.valueOf(mPId), PATH_LOGCAT);
            mLogDumper.start();
        }
    
        public void stop() {
            if (mLogDumper != null) {
                mLogDumper.stopLogs();
                mLogDumper = null;
            }
        }
    
        private class LogDumper extends Thread {
    
            private Process logcatProc;
            private BufferedReader mReader = null;
            private boolean mRunning = true;
            String cmds = null;
            private String mPID;
            private FileOutputStream out = null;
    
            public LogDumper(String pid, String dir) {
                mPID = pid;
                try {
                    out = new FileOutputStream(new File(dir, "logcat-" + MyDate.getFileName() + ".log"));
                } catch (FileNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
    
                /**
                 * 
                 * 日志等级:*:v , *:d , *:w , *:e , *:f , *:s
                 * 
                 * 显示当前mPID程序的 E和W等级的日志.
                 * 
                 * */
    
                // cmds = "logcat *:e *:w | grep "(" + mPID + ")"";
                cmds = "logcat  | grep "(" + mPID + ")"";//打印所有日志信息
                // cmds = "logcat -s way";//打印标签过滤信息
                //cmds = "logcat *:e *:i | grep "(" + mPID + ")"";
    
            }
    
            public void stopLogs() {
                mRunning = false;
            }
    
            @Override
            public void run() {
                try {
                    logcatProc = Runtime.getRuntime().exec(cmds);
                    mReader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()), 1024);
                    String line = null;
                    while (mRunning && (line = mReader.readLine()) != null) {
                        if (!mRunning) {
                            break;
                        }
                        if (line.length() == 0) {
                            continue;
                        }
                        if (out != null && line.contains(mPID)) {
                            out.write((MyDate.getDateEN() + "  " + line + "
    ")
                                    .getBytes());
                        }
                    }
    
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    if (logcatProc != null) {
                        logcatProc.destroy();
                        logcatProc = null;
                    }
                    if (mReader != null) {
                        try {
                            mReader.close();
                            mReader = null;
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                    if (out != null) {
                        try {
                            out.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                        out = null;
                    }
                }
            }
        }
    }
    LogcatHelper.java
    package com.why.project.logcathelperdemo.logcathelper;
    
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    /**
     * Created by HaiyuKing
     * Used
     */
    public class MyDate {
        public static String getFileName() {
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd",Locale.CHINA);
            String date = format.format(new Date(System.currentTimeMillis()));
            return date;// 2012-10-03
        }
    
        public static String getDateEN() {
            SimpleDateFormat format1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.CHINA);
            String date1 = format1.format(new Date(System.currentTimeMillis()));
            return date1;// 2012-10-03 23:41:31
        }
    }
    MyDate.java

    (2)新建MyApplication.java并添加以下代码

    package com.why.project.logcathelperdemo;
    
    import android.app.Application;
    
    import com.why.project.logcathelperdemo.logcathelper.LogcatHelper;
    
    /**
     * Created by HaiyuKing
     * Used 自定义application
     */
    
    public class MyApplication extends Application{
        @Override
        public void onCreate() {
            super.onCreate();
            //在应用中start LogcatHelper
            LogcatHelper.getInstance(this).start();
        }
    
        @Override
        public void onTerminate() {
            super.onTerminate();
            //在应用中stop LogcatHelper
            LogcatHelper.getInstance(this).stop();
        }
    
        @Override
        public void onTrimMemory(int level) {
            super.onTrimMemory(level);
        }
    
    }

    (3)在AndroidManifest.xml中申请MyApplication

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.why.project.logcathelperdemo">
    
        <application
            android:name=".MyApplication"
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
        </application>
    
    </manifest>

    (4)使用完之后,记得调用一下LogcatHelper.getInstance(this).stop();,MyApplication中执行的LogcatHelper.getInstance(this).stop();,可能有时候执行不到,保险起见,可以在第一个activity的onDestroy中执行LogcatHelper.getInstance(this).stop();

    三、使用方法

    正常执行Log方法即可。

    package com.why.project.logcathelperdemo;
    
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    
    import com.why.project.logcathelperdemo.logcathelper.LogcatHelper;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Log.v("MainActivity", "这是V日志");
            Log.d("MainActivity", "这是D日志");
            Log.i("MainActivity", "这是I日志");
            Log.w("MainActivity", "这是W日志");
            Log.e("MainActivity", "这是E日志");
        }
    
        @Override
        protected void onDestroy() {
            // TODO Auto-generated method stub
            super.onDestroy();
    
            //使用完后,调用stop
            LogcatHelper.getInstance(getApplicationContext()).stop();
        }
    }

    混淆配置

    参考资料

    Android将应用log信息保存文件

    Android将应用log信息保存文件

    项目demo下载地址

    https://github.com/haiyuKing/LogcatHelperDemo

  • 相关阅读:
    对position的认知观
    对于布局的见解
    Java中的多态
    继承中类型的转换
    继承中方法的覆盖
    继承条件下的构造方法调用
    Java函数的联级调用
    关于java中String的用法
    凯撒密码
    检查java 中有多少个构造函数
  • 原文地址:https://www.cnblogs.com/whycxb/p/9467099.html
Copyright © 2020-2023  润新知