1、增加依赖
implementation 'de.mindpipe.android:android-logging-log4j:1.0.3' implementation 'log4j:log4j:1.2.17'
2、增加权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3、CrashHandler捕捉全局异常
public class CrashHandler implements Thread.UncaughtExceptionHandler { private static CrashHandler sCrashHandler = new CrashHandler(); private SoftReference<Context> mContextRef; private String mApplicationId; private String TAG = "leo"; private CrashHandler() { } public static CrashHandler getInstance() { return sCrashHandler; } public void init(Context context, String applicationId) { Thread.setDefaultUncaughtExceptionHandler(this); mContextRef = new SoftReference<>(context.getApplicationContext()); mApplicationId = applicationId; } @Override public void uncaughtException(Thread thread, Throwable ex) { Log.i(TAG,"thread:"+thread.getName()); Log.i(TAG,"ex:"+ex); StringBuilder sb = new StringBuilder(); sb.append("\n********************************************************\n"); sb.append("\n********************************************************\n"); sb.append("Thread " + thread.getName() + " has crashed\n" + Log.getStackTraceString(ex)); Logger.info(sb.toString()); System.exit(0); } }
4、Logger输出日志到设备SD卡
public final class Logger { // Log tagg private static final String DEFAULT_LOG_TAG = "ZKBioID"; static { final LogConfigurator logConfigurator = new LogConfigurator(); logConfigurator.setFileName(Environment.getExternalStorageDirectory().getPath() + "/zkbioid.log"); logConfigurator.setRootLevel(Level.DEBUG); logConfigurator.setLevel("org.apache", Level.INFO); logConfigurator.setFilePattern("%d [%L] %m%n"); logConfigurator.setMaxFileSize(1024 * 1024 * 5); logConfigurator.setMaxBackupSize(20); logConfigurator.setImmediateFlush(true); logConfigurator.setUseFileAppender(true); logConfigurator.configure(); } static org.apache.log4j.Logger sLogger = org.apache.log4j.Logger.getLogger(DEFAULT_LOG_TAG); private Logger() { // Avoid instantiation } /** * Log a message object with the {@link Level#INFO INFO} Level. */ public static void info(Object message) { sLogger.info(message); } /** * Log a message object with the {@link Level#DEBUG DEBUG} level. */ public static void debug(Object message) { sLogger.debug(message); } /** * Log a message object with the {@link Level#ERROR ERROR} Level. */ public static void error(Object message) { sLogger.error(message); } /** * Log a message object with the {@link org.apache.log4j.Level#TRACE TRACE} level. */ public static void trace(Object message) { sLogger.trace(message); } /** * Log a message object with the {@link Level#FATAL FATAL} Level. */ public static void fatal(Object message) { sLogger.fatal(message); } /** * Set the level of this Category. If you are passing any of * <code>Level.DEBUG</code>, <code>Level.INFO</code>, * <code>Level.WARN</code>, <code>Level.ERROR</code>, * <code>Level.FATAL</code> as a parameter, you need to case them as * Level. */ public static void setLevel(Level level) { sLogger.setLevel(level); } }
5、初始化捕捉异常
public class CrashHandelApplication extends Application { @Override public void onCreate() { super.onCreate(); CrashHandler.getInstance().init(this, "com.crash.handel.demo"); } }
6、进行测试
public class MainActivity extends AppCompatActivity { private String TAG = "leo"; private TextView tvTest; private Button btnTest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); } private void initView(){ btnTest=findViewById(R.id.btnTest); btnTest.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { createNullPointer(); } }); } private void createNullPointer() { tvTest.setText("测试"); } }
最后,设备端的sd卡会看到一个生产的文件zkbioid.log。里面有打印出错误日志!