android Timber日志打印
突然间代码里提示Log日志警告了,一看提醒提示使用Timber
Timber使用很简单,可以配置一个日志过滤的东西,就是每个打印的日志都会走这里,可以根据自己的需要做保存或其他。
引入Timber
依赖implementation 'com.jakewharton.timber:timber:4.7.1'
// rxJava
implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
implementation 'io.reactivex.rxjava2:rxjava:2.2.0'
// 权限
implementation 'com.github.tbruyelle:rxpermissions:0.10.2'
很简单的配置,在Application中设置一个过滤器
Timber.plant(new CrashReportingTree());
import android.annotation.SuppressLint;
import android.os.Environment;
import android.util.Log;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import io.reactivex.Observable;
import io.reactivex.ObservableEmitter;
import io.reactivex.ObservableOnSubscribe;
import io.reactivex.observers.DefaultObserver;
import io.reactivex.schedulers.Schedulers;
import timber.log.Timber;
import static android.util.Log.INFO;
/**
* 作者: 大海
* 时间: 2018/10/30
* 描述: 打印日志,保存到本地
*/
public final class CrashReportingTree extends Timber.Tree {
/**
* 是否记录log
* @param tag tag
* @param priority 级别
* @return true 往下走log,否则不走
*/
@Override
protected boolean isLoggable(@Nullable String tag, int priority) {
return priority >= INFO;
}
/**
* 自己处理对应的日志信息
* @param priority 级别
* @param tag tag
* @param message message
* @param t 错误信息
*/
@Override
protected void log(int priority, @Nullable final String tag, @NotNull final String message, @Nullable final Throwable t) {
/* 如果日志界别是v或d就不做任何处理 */
if (priority == Log.VERBOSE || priority == Log.DEBUG) {
return;
}
if (BuildConfig.DEBUG) {
logcat(tag,message,t);
}
Observable.create(new ObservableOnSubscribe<Boolean>() {
@Override
public void subscribe(ObservableEmitter<Boolean> emitter){
try {
saveLogcat(tag,message,t);
emitter.onNext(true);
} catch (Exception e) {
emitter.onError(e);
}
}})
.subscribeOn(Schedulers.io())
.subscribe(new DefaultObserver<Boolean>() {
@Override
public void onNext(Boolean aBoolean) {
}
@Override
public void onError(Throwable e) {
}
@Override
public void onComplete() {
}
});
}
/**
* 打印日志
*/
@SuppressLint("LogNotTimber")
private void logcat(@Nullable String tag, @NotNull String message, @Nullable Throwable t) {
if (tag==null) {
if (t==null) {
Log.e("TAG", message);
} else {
Log.e("TAG", message ,t );
}
} else {
if (t==null) {
Log.e(tag, message);
} else {
Log.e(tag, message ,t );
}
}
}
/**
* 保存日志
*/
@SuppressLint("LogNotTimber")
private void saveLogcat(@Nullable String tag, @NotNull String message, @Nullable Throwable t) throws Exception{
StringBuilder sb = new StringBuilder();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss",Locale.getDefault());
sb.append(sdf.format(new Date())).append(" 日志:");
sb.append("[").append(tag).append("] {").append(message).append("}\n");
if (t!=null) {
Writer writer = new StringWriter();
PrintWriter pw = new PrintWriter(writer);
t.printStackTrace(pw);
Throwable cause = t.getCause();
// 循环着把所有的异常信息写入writer中
while (cause != null) {
cause.printStackTrace(pw);
cause = cause.getCause();
}
pw.close();// 记得关闭
String result = writer.toString();
sb.append("错误信息:").append("\n").append(result);
}
// 目录
File dir = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
+ File.separator + MyApp.mContext.getPackageName() + File.separator + "log");
if (!dir.exists()) {
dir.mkdirs();
}
SimpleDateFormat fileFormat = new SimpleDateFormat("yyyy-MM-dd",Locale.getDefault());
FileOutputStream fos = new FileOutputStream(new File(dir,fileFormat.format(new Date())),true);
fos.write(sb.toString().getBytes());
fos.flush();
fos.close();
}
}
日志记录还算清晰
最后注意权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
,但是如果权限被拒绝了由于做了异常处理,不会导致闪退
Disposable subscribe = new RxPermissions(this)
.request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
.subscribe(new Consumer<Boolean>() {
@Override
public void accept(Boolean aBoolean) throws Exception {
}
});