Retrofit 自定义注解 实现可选择性的打印接口日志

序言

有时候我们需要打印okhttp的日志,但是现在的日志拦截器,不能做到接口级别的日志输出控制。要么就是全部打印。这样很影响调试效率。所以我在这块做了一些探索。

使用效果

普通输出

只需要在要打印日志的接口上添加 @PrintLog 注解就可以打印,没有添加的接口不会打印
在这里插入图片描述

打印出来的日志

tag通过初始化的时候指定

httpClient.addInterceptor(new LoginControlInterceptor("ok_http_log"));

在这里插入图片描述

支持自定义tag

参数定义

在这里插入图片描述

输出效果在这里插入图片描述

使用

日志打印功能基于下面的库实现,需要添加下面的库为支撑。


    implementation 'com.github.fengzhizi715.okhttp-logging-interceptor:core:v1.1.4'

下面三个自定义的类

AndroidLogProxy

package com.trs.library.rx2.http.http_log;

import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import cn.netdiscovery.http.interceptor.log.LogProxy;


/**
 * <pre>
 * Created by zhuguohui
 * Date: 2024/8/8
 * Time: 10:34
 * Desc:
 * </pre>
 */
public class AndroidLogProxy implements LogProxy {
    private String tempTag;

    @Override
    public void d(@NonNull String s, @NonNull String s1) {

        Log.d(getTag(s), s1);
    }
    private String getTag(String tag){
        if(!TextUtils.isEmpty(tempTag)){
            return tempTag;
        }else{
            return tag;
        }
    }

    @Override
    public void e(@NonNull String s, @NonNull String s1) {
        Log.e(getTag(s), s1);
    }

    @Override
    public void w(@NonNull String s, @NonNull String s1) {
        Log.w(getTag(s), s1);
    }

    @Override
    public void i(@NonNull String s, @NonNull String s1) {
        Log.i(getTag(s), s1);
    }

    public void setTempTag(String tempTag) {
        this.tempTag = tempTag;
    }


}


LoginControlInterceptor

package com.trs.library.rx2.http.http_log;

import com.trs.library.BuildConfig;

import java.io.IOException;
import java.lang.annotation.Annotation;

import cn.netdiscovery.http.interceptor.LoggingInterceptor;
import cn.netdiscovery.http.interceptor.log.LogManager;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import retrofit2.Invocation;

/**
 * <pre>
 * Created by zhuguohui
 * Date: 2024/8/8
 * Time: 11:33
 * Desc:控制是否输出日志的拦截器
 * </pre>
 */
public class LoginControlInterceptor implements Interceptor {
    private final AndroidLogProxy androidLogProxy;
    Interceptor logInterceptor;

    public LoginControlInterceptor(String tag) {
        androidLogProxy = new AndroidLogProxy();
        LogManager.INSTANCE.logProxy(androidLogProxy);
        logInterceptor = new LoggingInterceptor.Builder()
                .loggable(BuildConfig.DEBUG) // TODO: 发布到生产环境需要改成false
                .request()
                .requestTag(tag)
                .response()
                .responseTag(tag)
                .build();
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Invocation invocation = request.tag(Invocation.class);
        Annotation[] declaredAnnotations = invocation.method().getDeclaredAnnotations();
        boolean printLog = false;
        String tempTag = null;
        for (Annotation ano : declaredAnnotations) {
            if (ano.annotationType() == PrintLog.class) {
                printLog = true;
                tempTag = ((PrintLog) ano).value();
            }
        }
        if (printLog) {
            //需要打印日志
            if (logInterceptor != null) {
                androidLogProxy.setTempTag(tempTag);
                Response response = logInterceptor.intercept(chain);
                androidLogProxy.setTempTag(null);
                return response;
            }
        }
        return chain.proceed(chain.request());
    }
}


注解 PrintLog

package com.trs.library.rx2.http.http_log;

import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

/**
 * <pre>
 * Created by zhuguohui
 * Date: 2024/8/8
 * Time: 16:20
 * Desc:用于打印日志
 * </pre>
 */
@Target(METHOD)
@Retention(RUNTIME)
public @interface PrintLog {

    String value() default "";
}



使用

httpClient.addInterceptor(new LoginControlInterceptor("ok_http_log"));

难点

难点主要是怎么在拦截器中获取自定义注解,看来Retrofit的源码,它把被反射的方法保存在。tag的Invocation中。通过下面的方法获取。

        Request request = chain.request();
        Invocation invocation = request.tag(Invocation.class);
        Annotation[] declaredAnnotations = invocation.method().getDeclaredAnnotations();
  • 8
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值