Android手把手教你实现日志打印框架

架构

Log框架分析:

        1.全局配置类HiLogConfig

        2.全局管理类HiLogManager

        3. 对外暴露的方法HiLog

        4.Log的类型HiLogType

        5.格式化接口HiLogFormatter

        6.线程格式化HiThreadFormatter ,堆栈格式化HiStackTraceFormatter 实现格式化接口          HiLogFormatter

        7.Log打印器接口HiLogPrinter

        8.日志打印器HiConsolePrinter , 悬浮窗视图打印器HiViewPrinter

        9.HiLogMo模型类


一配置Config配置类

package com.junbao.library.log;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 1:42 下午
 * desc   : log配置类
 */
public abstract class HiLogConfig {
    //一行最大输出长度
    static int MAX_LEN= 512;
HiStackTraceFormatter();

    /**
     * 配置全局tag
     * @return
     */
    public String getGlobalTag(){
        return "HiLog";
    }

    /**
     * 配置全局启用
     * @return
     */
    public boolean enable(){
        return true;
    }

   
    /**
     * 是否包含线程信息
     * @return
     */
    public boolean includeThread(){
        return false;
    }

    /**
     * 打印堆栈信息级别 深度
     * @return
     */
    public int stackTraceDepth(){
        return 5;
    }


}

二.配置全局管理类

package com.junbao.library.log;

import androidx.annotation.NonNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 1:42 下午
 * desc   : log管理类
 */
public class HiLogManager {

    private static HiLogManager instance;
    private HiLogConfig config;

    private HiLogManager(HiLogConfig config ) {
        this.config = config;
    }

    public static HiLogManager getInstance(){
        return instance;
    }

    public static void init(@NonNull HiLogConfig config){
        instance = new HiLogManager(config);
    }

    /**
     * 获取config对象
     * @return
     */
    public HiLogConfig getConfig(){
        return config;
    }

}

三.定义日志打印类型

public class HiLogType {

    @IntDef({V,D,I,W,E,A})
    //保留在源码级别
    @Retention(RetentionPolicy.SOURCE)
    public @interface TYPE{}

    public final static int V = Log.VERBOSE;
    public final static int D = Log.DEBUG;
    public final static int I = Log.INFO;
    public final static int W = Log.WARN;
    public final static int E = Log.ERROR;
    public final static int A = Log.ASSERT;
}

        

        

四.配置HiLog对外暴露的方法

package com.junbao.library.log;

import android.util.Log;

import androidx.annotation.NonNull;

import java.util.Arrays;
import java.util.List;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 1:41 下午
 * desc   : Log
 */
public class HiLog {
    private static final String HI_LOG_PACKAGE;

    static {
        String className = HiLog.class.getName();
        HI_LOG_PACKAGE = className.substring(0 , className.lastIndexOf(".")+1);
    }

    public static void v(Object... contents) {
        log(HiLogType.V, contents);
    }

    public static void vt(String tag, Object... contents) {
        log(HiLogType.V, tag, contents);
    }


    public static void d(Object... contents) {
        log(HiLogType.D, contents);
    }

    public static void dt(String tag, Object... contents) {
        log(HiLogType.D, tag, contents);
    }
    public static void i(Object... contents) {
        log(HiLogType.I, contents);
    }

    public static void it(String tag, Object... contents) {
        log(HiLogType.I, tag, contents);
    }

    public static void w(Object... contents) {
        log(HiLogType.W, contents);
    }

    public static void wt(String tag, Object... contents) {
        log(HiLogType.W, tag, contents);
    }

    public static void e(Object... contents) {
        log(HiLogType.E, contents);
    }

    public static void et(String tag, Object... contents) {
        log(HiLogType.E, tag, contents);
    }

    public static void a(Object... contents) {
        log(HiLogType.A, contents);
    }

    public static void at(String tag, Object... contents) {
        log(HiLogType.A, tag, contents);
    }


    public static void log(@HiLogType.TYPE int type, Object... contents) {
        log(type, HiLogManager.getInstance().getConfig().getGlobalTag(), contents);
    }

    public static void log(@HiLogType.TYPE int type, String tag, Object... contents) {
        log(HiLogManager.getInstance().getConfig(), type, tag, contents);
    }

    public static void log(HiLogConfig config, @HiLogType.TYPE int type, String tag, Object... contents) {
        //如果false ,则代表 不输出
        if (!config.enable()){
            return;
        }
        StringBuilder sb = new StringBuilder();

        //1.我们需要先对日志进行格式化
        String body = parseBody(contents , config);
        sb.append(body);

       
        Log.println(type , tag , sb.toString());
    }

    /**
     * 格式化日志
     * @param contents
     * @param config
     * @return
     */
    private static String parseBody(@NonNull Object[] contents , @NonNull HiLogConfig config){
        
        StringBuilder sb = new StringBuilder();
        for (Object content : contents) {
            sb.append(content.toString()).append(";");
        }
        if (sb.length() > 0 ){
            sb.deleteCharAt(sb.length()-1);
        }
        return sb.toString();
    }
}


测试

package com.junbao.androidlibrary

import android.app.Application
import com.junbao.library.log.HiLogConfig
import com.junbao.library.log.HiLogManager

/**
 *    author : Majunbao
 *    github : https://github.com/MaJunBaox
 *    time   : 2022/5/13 2:04 下午
 *    desc   :
 */
class MyApplication:Application() {
    override fun onCreate() {
        super.onCreate()
        HiLogManager.init(object : HiLogConfig() {
            override fun getGlobalTag(): String {
                return "liuyi"
            }

            override fun enable(): Boolean {
                return true
            }

        })
    }
}
package com.junbao.androidlibrary

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.junbao.library.log.*

/**
 *    author : Majunbao
 *    github : https://github.com/MaJunBaox
 *    time   : 2022/5/13 1:38 下午
 *    desc   : 
 */
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<View>(R.id.tv_log).setOnClickListener {
            printLog()
        }
       
    }

    private fun printLog() {
        HiLog.e("Majunbao Test Log")
    }
}

五.定义打印器

package com.junbao.library.log;

import androidx.annotation.NonNull;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 2:07 下午
 * desc   : log输出接口
 */
public interface HiLogPrinter {
    void print(@NonNull HiLogConfig config , int level , String tag , @NonNull String printString);
}

 实现日志打印器

package com.junbao.library.log;

import static com.junbao.library.log.HiLogConfig.MAX_LEN;

import android.util.Log;

import androidx.annotation.NonNull;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 2:08 下午
 * desc   : 日志打印器
 */
public class HiConsolePrinter implements HiLogPrinter{

    /**
     * 分析: 获取日志长度 ,进行分行打印
     * HiLogConfig中配置下最大一行显示长度
     * @param config
     * @param level
     * @param tag
     * @param printString
     */

    @Override
    public void print(@NonNull HiLogConfig config, int level, String tag, @NonNull String printString) {
        //获取日志长度
        int len = printString.length();
        //行数 = 总长度 / 一行最大长度
        int rowCount = len / MAX_LEN;
        //行数不为0时
        if (rowCount > 0 ){
            StringBuilder sb = new StringBuilder();
            int index = 0 ;
            //遍历行数
            for (int i = 0; i < rowCount; i++) {
                sb.append(printString.substring(index , index+MAX_LEN));
                index = i  + MAX_LEN;
            }
            if (index!=len){
                sb.append(printString.substring(index, len));
            }
        }
        //行数为0 ,输出剩余部分
        Log.println(level , tag , printString);
    }
}

六.定义格式化接口

package com.junbao.library.log;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 2:54 下午
 * desc   : 日志解析器
 */
public interface HiLogFormatter <T>{

    String format(T data);
}

  实现线程格式化 ,和 堆栈信息格式化

package com.junbao.library.log;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 2:55 下午
 * desc   : 线程格式化
 */
public class HiThreadFormatter implements HiLogFormatter<Thread>{
    @Override
    public String format(Thread data) {
        return "Thread:"+data.getName();
    }
}

     创建堆栈信息工具类

package com.junbao.library.log;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 4:10 下午
 * desc   : 堆栈打印工具类
 */
public class HiStackTraceUtil {

    public static StackTraceElement[] getCroppedRealStackTrack(StackTraceElement[] stackTrace, String ignorePackage, int maxDepth) {
        return cropStackTrace(getRealStackTrack(stackTrace, ignorePackage), maxDepth);
    }

    private static StackTraceElement[] getRealStackTrack(StackTraceElement[] stackTrace, String ignorePackage) {
        int ignoreDepth = 0;
        int allDepth = stackTrace.length;
        String className;
        for (int i = allDepth - 1 ; i >= 0 ; i--){
            //获取堆栈包名
            className = stackTrace[i].getClassName();
            if (ignorePackage !=null && className.startsWith(ignorePackage)){
                ignoreDepth= i+1;
                break;
            }
        }

        int realDepth = allDepth - ignoreDepth;
        StackTraceElement[] realStack = new StackTraceElement[realDepth];
        System.arraycopy(stackTrace, ignoreDepth, realStack, 0, realDepth);
        return realStack;
    }


    /**
     *
     * @param callStack
     * @param maxDepth
     * @return
     */
    public static StackTraceElement[] cropStackTrace(StackTraceElement[] callStack, int maxDepth) {
        //获取堆栈的 长度
        int realDepth = callStack.length;
        if (maxDepth > 0) {
            //获取最小深度
            realDepth = Math.min(maxDepth, realDepth);
        }
        //创建新的堆栈
        StackTraceElement[] realStack = new StackTraceElement[realDepth];
        //copy
        System.arraycopy(callStack, 0, realStack, 0, realDepth);
        return realStack;
    }
}
package com.junbao.library.log;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 3:53 下午
 * desc   : 堆栈信息格式化
 */
public class HiStackTraceFormatter implements HiLogFormatter<StackTraceElement[]>{
    @Override
    public String format(StackTraceElement[] stackTrace) {
        StringBuilder sb = new StringBuilder(128);
        if (stackTrace == null || stackTrace.length == 0 ){
            return  null;
        }else if (stackTrace.length == 1){
            return "\t- "+stackTrace[0].toString();
        }else {
            //
            for (int i = 0, len = stackTrace.length; i < len ; i++) {
                if (i == 0 ){
                    sb.append("stackTrace: \n");
                }
//                0!=4
//                        1!=4
//                                2!=4
//                                        3!=4

                if (i != len-1){
                    sb.append("\t├ ");
                    sb.append(stackTrace[i].toString());
                    sb.append("\n");
                }else {
                    sb.append("\t└ ");
                    sb.append(stackTrace[i].toString());
                }
            }
        }
        return sb.toString();
    }
}

HiLogConfig创建静态

 static HiThreadFormatter HI_THREAD_FORMATTER = new HiThreadFormatter();
 static HiStackTraceFormatter HI_STACK_TRACE_FORMATTER = new HiStackTraceFormatter();

HiLog中输出打印

public static void log(HiLogConfig config, @HiLogType.TYPE int type, String tag, Object... contents) {
        //如果false ,则代表 不输出
        if (!config.enable()){
            return;
        }
        StringBuilder sb = new StringBuilder();

        if (config.includeThread()){
            String threadInfo = HiLogConfig.HI_THREAD_FORMATTER.format(Thread.currentThread());
            sb.append(threadInfo).append("\n");
        }

        if (config.stackTraceDepth() > 0 ){
            String stackTrace = HiLogConfig.HI_STACK_TRACE_FORMATTER.format(
                    HiStackTraceUtil.getCroppedRealStackTrack(new Throwable().getStackTrace() , HI_LOG_PACKAGE , config.stackTraceDepth())
            );
            sb.append(stackTrace).append("\n");
        }

        //1.我们需要先对日志进行格式化
        String body = parseBody(contents , config);
        sb.append(body);

       
        Log.println(type , tag , sb.toString());
    }

配置日志打印器

HiLogConfig中添加

    /**
     * 打印器集合
     * @return
     */
    public HiLogPrinter[] printers() {
        return null;
    }

    /**
     * 配置Gson解析器
     * @return
     */
    public JsonParser injectJsonParser() {
        return null;
    }

    public interface JsonParser{
        String toJson(Object src);
    }

HiLog中更改代码

 public static void log(HiLogConfig config, @HiLogType.TYPE int type, String tag, Object... contents) {
        //如果false ,则代表 不输出
        if (!config.enable()){
            return;
        }
        StringBuilder sb = new StringBuilder();

        if (config.includeThread()){
            String threadInfo = HiLogConfig.HI_THREAD_FORMATTER.format(Thread.currentThread());
            sb.append(threadInfo).append("\n");
        }

        if (config.stackTraceDepth() > 0 ){
            String stackTrace = HiLogConfig.HI_STACK_TRACE_FORMATTER.format(
                    HiStackTraceUtil.getCroppedRealStackTrack(new Throwable().getStackTrace() , HI_LOG_PACKAGE , config.stackTraceDepth())
            );
            sb.append(stackTrace).append("\n");
        }

        //1.我们需要先对日志进行格式化
        String body = parseBody(contents , config);
        sb.append(body);

        List<HiLogPrinter> printers = config.printers()!=null ? Arrays.asList(config.printers()) : HiLogManager.getInstance().getPrinters();

        for (HiLogPrinter printer : printers) {
            printer.print(config , type , tag , sb.toString());
        }
      //  Log.println(type , tag , sb.toString());
    }
    /**
     * 格式化日志
     * @param contents
     * @param config
     * @return
     */
    private static String parseBody(@NonNull Object[] contents , @NonNull HiLogConfig config){
        if (config.injectJsonParser()!=null){
            if (contents.length == 1 && contents[0] instanceof  String){
                return (String) contents[0];
            }
            return config.injectJsonParser().toJson(contents);
        }
        StringBuilder sb = new StringBuilder();
        for (Object content : contents) {
            sb.append(content.toString()).append(";");
        }
        if (sb.length() > 0 ){
            sb.deleteCharAt(sb.length()-1);
        }
        return sb.toString();
    }

MyApplication中配置

class MyApplication:Application() {
    override fun onCreate() {
        super.onCreate()
        HiLogManager.init(object : HiLogConfig() {
            override fun getGlobalTag(): String {
                return "liuyi"
            }

            override fun enable(): Boolean {
                return true
            }

            override fun includeThread(): Boolean {
                return true
            }

            override fun injectJsonParser(): JsonParser {
                return JsonParser {
                    src -> Gson().toJson(src)
                }
            }
        } ,HiConsolePrinter())
    }
}

测试

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        findViewById<View>(R.id.tv_log).setOnClickListener {
            printLog()
        }

    }

    private fun printLog() {
        HiLog.e("Majunbao Test Log")

        Thread{
            HiLog.e("线程测试")
        }.start()

        HiLog.log(object : HiLogConfig() {
            override fun includeThread(): Boolean {
                return false
            }
        }, HiLogType.E, "---", "5566")
        HiLog.a("9900")
    }
}

扩展

实现悬浮窗,可在页面上看到控制台信息

1.定义Log模型类

package com.junbao.library.log;

import java.text.SimpleDateFormat;
import java.util.Locale;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 6:37 下午
 * desc   : log数据类
 */
public class HiLogMo {
    private static SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd HH:mm:ss", Locale.CHINA);
    public long timeMillis;
    public int level;
    public String tag;
    public String log;

    public HiLogMo(long timeMillis, int level, String tag, String log) {
        this.timeMillis = timeMillis;
        this.level = level;
        this.tag = tag;
        this.log = log;
    }

    public String flattenedLog() {
        return getFlattened() + "\n" + log;
    }

    public String getFlattened() {
        return format(timeMillis) + '|' + level + '|' + tag + "|:";
    }

    private String format(long timeMillis) {
        return sdf.format(timeMillis);
    }
}

2.创建HiViewPrinter类

package com.junbao.library.log;

import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.junbao.library.R;

import java.util.ArrayList;
import java.util.List;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 6:34 下午
 * desc   : view打印器
 */
public class HiViewPrinter implements HiLogPrinter{

    private final LogAdapter adapter;
    private final HiViewPrinterProvider viewPrinterProvider;
    private final RecyclerView recyclerView;

    public HiViewPrinter(Activity activity) {
        FrameLayout rootView = activity.findViewById(android.R.id.content);
        recyclerView = new RecyclerView(activity);
        recyclerView.setLayoutManager(new LinearLayoutManager(recyclerView.getContext()));
        adapter = new LogAdapter(LayoutInflater.from(recyclerView.getContext()));
        recyclerView.setAdapter(adapter);
        viewPrinterProvider = new HiViewPrinterProvider(rootView, recyclerView);
    }

    /**
     * 获取
     * @return
     */
    @NonNull
    public HiViewPrinterProvider getViewPrinterProvider() {
        return viewPrinterProvider;
    }

    @Override
    public void print(@NonNull HiLogConfig config, int level, String tag, @NonNull String printString) {
        adapter.addItem(new HiLogMo(System.currentTimeMillis() , level , tag , printString));
        // 滚动到对应的位置
        recyclerView.smoothScrollToPosition(adapter.getItemCount() - 1);
    }

    public static class LogAdapter extends RecyclerView.Adapter<LogViewHolder>{

        private final LayoutInflater inflater;
        List<HiLogMo> logs = new ArrayList<>();

        /**
         * 添加新数据
         * @param log
         */
        public void addItem(HiLogMo log){
            logs.add(log);
            notifyItemInserted(logs.size()-1);
        }

        public LogAdapter(LayoutInflater inflater) {
           this.inflater = inflater;
        }

        @NonNull
        @Override
        public LogViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View itemView = inflater.inflate(R.layout.hilog_item , parent , false);
            return new LogViewHolder(itemView);
        }

        @Override
        public void onBindViewHolder(@NonNull LogViewHolder holder, int position) {
            HiLogMo logItem = logs.get(position);

            int color = getHighlightColor(logItem.level);
            holder.tagView.setTextColor(color);
            holder.messageView.setTextColor(color);

            holder.tagView.setText(logItem.getFlattened());
            holder.messageView.setText(logItem.log);
        }

        @Override
        public int getItemCount() {
            return logs==null ? 0 : logs.size();
        }

        /**
         * 跟进log级别获取不同的高了颜色
         *
         * @param logLevel log 级别
         * @return 高亮的颜色
         */
        private int getHighlightColor(int logLevel) {
            int highlight;
            switch (logLevel) {
                case HiLogType.V:
                    highlight = 0xffbbbbbb;
                    break;
                case HiLogType.D:
                    highlight = 0xffffffff;
                    break;
                case HiLogType.I:
                    highlight = 0xff6a8759;
                    break;
                case HiLogType.W:
                    highlight = 0xffbbb529;
                    break;
                case HiLogType.E:
                    highlight = 0xffff6b68;
                    break;
                default:
                    highlight = 0xffffff00;
                    break;
            }
            return highlight;
        }
    }

    public static class LogViewHolder extends RecyclerView.ViewHolder{

        TextView tagView;
        TextView messageView;

        public LogViewHolder(@NonNull View itemView) {
            super(itemView);
            tagView = itemView.findViewById(R.id.tag);
            messageView = itemView.findViewById(R.id.message);
        }
    }
}

package com.junbao.library.log;

import android.graphics.Color;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;

import androidx.recyclerview.widget.RecyclerView;

/**
 * author : Majunbao
 * github : https://github.com/MaJunBaox
 * time   : 2022/5/13 6:41 下午
 * desc   : logcat悬浮实现
 */

public class HiViewPrinterProvider {
    private FrameLayout rootView;
    private RecyclerView recyclerView;
    private View floatingView;
    private boolean isOpen;
    private FrameLayout logView;

    public HiViewPrinterProvider(FrameLayout rootView, RecyclerView recyclerView) {
        this.rootView = rootView;
        this.recyclerView = recyclerView;
    }

    private static final String TAG_FLOATING_VIEW = "TAG_FLOATING_VIEW";
    private static final String TAG_LOG_VIEW = "TAG_LOG_VIEW";

    /**
     * 展示悬浮
     */
    public void showFloatingView(){
        if (rootView.findViewWithTag(TAG_FLOATING_VIEW) != null){
            return;
        }
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.BOTTOM | Gravity.END;
        View floatingView = getFloatingView();
        floatingView.setTag(TAG_FLOATING_VIEW);
        floatingView.setBackgroundColor(Color.BLACK);
        floatingView.setAlpha(0.8f);
        params.bottomMargin = HiDisplayUtil.dp2px(100, rootView.getResources());
        rootView.addView(floatingView , params);
    }

    /**
     * 绘制悬浮
     * @return
     */
    private View getFloatingView() {
        if (floatingView !=null){
            return floatingView;
        }
        TextView textView = new TextView(rootView.getContext());
        textView.setOnClickListener(view -> {
            if (!isOpen){
                showLogView();
            }
        });

        textView.setText("HiLog");
        return floatingView = textView;
    }

    /**
     * 展示logCat
     */
    private void showLogView() {
        if (rootView.findViewWithTag(TAG_LOG_VIEW) !=null){
            return;
        }

        FrameLayout.LayoutParams params =
                new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, HiDisplayUtil.dp2px(160, rootView.getResources()));
        params.gravity = Gravity.BOTTOM;
        View logView = genLogView();
        logView.setTag(TAG_LOG_VIEW);
        rootView.addView(genLogView() , params);
        isOpen = true;
    }

    /**
     * 绘制loacat
     * @return
     */
    private View genLogView() {
        if (logView!=null){
            return logView;
        }
        FrameLayout logView = new FrameLayout(rootView.getContext());
        logView.setBackgroundColor(Color.BLACK);
        logView.addView(recyclerView);


        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        params.gravity = Gravity.END;
        TextView closeView = new TextView(rootView.getContext());
        closeView.setOnClickListener(v ->{
            closeLogView();
        });
        closeView.setText("Close");
        logView.addView(closeView , params);
        return this.logView = logView;
    }

    /**
     * 关闭logcat窗口
     */
    private void closeLogView() {
        isOpen = false;
        rootView.removeView(genLogView());
    }

}

使用

package com.junbao.androidlibrary

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import com.junbao.library.log.*

/**
 *    author : Majunbao
 *    github : https://github.com/MaJunBaox
 *    time   : 2022/5/13 1:38 下午
 *    desc   : 
 */
class MainActivity : AppCompatActivity() {


    var viewPrinter : HiViewPrinter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        viewPrinter = HiViewPrinter(this)


        findViewById<View>(R.id.tv_log).setOnClickListener {
            printLog()
        }

        viewPrinter!!.viewPrinterProvider.showFloatingView()


    }

    private fun printLog() {
        HiLogManager.getInstance().addPrinter(viewPrinter)
        HiLog.e("Majunbao Test Log")

        Thread{
            HiLog.e("线程测试")
        }.start()

        HiLog.log(object : HiLogConfig() {
            override fun includeThread(): Boolean {
                return false
            }
        }, HiLogType.E, "---", "5566")
        HiLog.a("9900")
    }
}

 

 

到此Log框架封装完毕
码云仓库:AndroidLibrary: 安卓通用组件库

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值