鸿蒙日志工具组件,代码已开源!

那片海 2021-07-02 14:29:37 3945

基于安卓平台的日志工具组件 Timber, 实现鸿蒙的功能化迁移和重构,代码已经开源,欢迎各位开发者提出宝贵意见。

开源地址:
https://gitee.com/isrc_ohos/timber_ohos

Timber_ohos 是一个带有小型可扩展 API 的日志工具组件,它可以给开发者提供统一的 API 接口,来记录不同类型的日志,帮助开发者管理不同类型的 log。

同时,Timber_ohos 是项目开发时的 log 开关,通过此开关控制 log 的打印与关闭,从而形成不同的软件版本。该组件功能丰富且使用简单高效,可以被广泛应用于软件项目开发中。

组件效果展示

①测试界面

如图 1 所示,这是一个为了测试 Timber_ohos 功能而简单构建的 UI 页面。点击“测试”按钮即可输出相应的 log。

图 1:测试界面 UI 图

②Log 打印

Timber 类的静态方法调用如图 2 中的(a)图所示。运行项目后查看 HiLog 显示,可以看到实时打印出来的日志,如图 2 中的(b)图所示。

图 2:HiLog 日志打印

Sample 解析

①Tree 的使用

Timber_ohos 将不同的日志操作以树(Tree)的概念进行表示,种植一种树就拥有一种日志记录功能,种植多种树就拥有多种日志记录的功能。

树的种类有很多,常见的树有:DebugTree、RealeseTree、FileTree、CrashReportingTree 等,这些树都是继承自 Tree 类。

DebugTree:对所有的日志进行记录。

RealeseTree:只对 warn,error,wtf 信息进行记录。

FileTree:在运行时将日志记录到文件中。

CrashReportingTree:对应用崩溃时的信息进行记录。

Timber_ohos 中默认已经种植了 DebugTree,由于 Timber_ohos 本身是一个可扩展的框架。

因此开发者想得到其他类型的 Log 日志时,就需要自己实现一个日志记录类 ,然后种植到 Timber_ohos 中即可。

②Sample 的实现

Sample 部分需要添加日志记录种类,并负责整体显示布局的搭建。首先为 Timber_ohos 组件添加想要的任何 Tree 子类实例(这里使用的是 DebugTree)。

然后设置简单的按钮监听器,当按动按钮时在鸿蒙常规 HiLog 中出现调试日志。

下面将详细介绍组件的使用方法:

步骤 1:种树(添加 Tree 子类实例)。

步骤 2:创建整体的显示布局。

步骤 3:导入相关类并设置按钮监听。

步骤 4:使用 Tree 实例。

(1)种树(添加 Tree 子类实例)

本步骤是在 ExampleApp 类的 onInitialize() 方法中实现的。首先需要创建 Tree 子类实例,然后调用 Timber 的 plant() 方法,同时将实例作为 plant() 方法的参数,这个过程叫做“种树”。
Timber.plant(new Timber.DebugTree(0x001f00));

(2)创建整体的显示布局

在 XML 文件中创建一个 DirectionalLayout 作为整体显示布局,宽度和高度都跟随父控件变化而调整。

创建两个组件,分别是 Text 组件和 Button 组件,用于控制组件效果显示。

整体显示布局如图 1 所示:
<DirectionalLayout
xmlns:ohos="http://schemas.huawei.com/res/ohos"
ohos:height="match_parent"
ohos:width="match_parent"
ohos:orientation="vertical"
ohos:padding="32vp"
ohos:background_element="#ffffff"
ohos:alignment="horizontal_center">
<Text //“测试”提示
ohos:height="match_content"
ohos:width="match_content"
ohos:layout_alignment="horizontal_center"
ohos:text="Timber测试"
ohos:text_size="35fp"/>
<Button //控制按钮
ohos:id="$+id:btn1"
ohos:height="match_content"
ohos:width="match_content"
ohos:top_margin="35vp"
ohos:text_size="25fp"
ohos:background_element="#FF51A8DD"
ohos:padding="10vp"
ohos:text="测试"/>

(3)导入显示布局并设置按钮监听

在 MainAbilitySlice 中,整体显示布局也需要通过 super.setUIContent() 方法进行设置,才能生效并成功显示。

然后给按钮设置点击事件,当用户需要使用 Tree 子类实例时,可通过手指进行点击。
super.setUIContent(ResourceTable.Layout_ability_main);//设置整体显示布局
findComponentById(ResourceTable.Id_btn1).setClickedListener(new Component.ClickedListener() {
...//按钮的点击事件
}

(4)使用 Tree 实例

当用户需要打印调试日志的时候,调用 Timber 的静态方法,就会在鸿蒙常规 HiLog 上出现调试日志。调试日志如组件效果展示部分的图 2 所示。
Timber.e ("Timber.e 测试成功!!!");
Timber.d ("Timber.d 测试成功!!!");
Timber.i ("Timber.i 测试成功!!!");
Timber.w ("Timber.w 测试成功!!!");
Timber.wtf ("Timber.wtf测试成功!!!");

Library 解析

Library 主要为 Timber_ohos 组件提供日志输出的统一接口。

以 Sample 中种植的调试树(DebugTree)为例,当使用 Timber 的静态方法 Timber.e 时,从 MainAbilitySlice 到 Timber.e 打印 log 的地方可以分为 5 个步骤。

整体调用的流程如图 3 所示:

图 3:调用顺序图

下面我们着重介绍树(Tree 类)在 Library 中的实现,核心算法 prepareLog() 内部的逻辑结构这两个方面的内容。

①树(Tree)的实现

Tree 类是一种概念形式的日志操作,具体可分为DebugTree、ReleaseTree、FileTree 等。

而在 Library 内部,Tree 类也实现了一系列方法,以便于对森林中的各类树进行增加、删除、修改等操作。

(1)在 Timber_ohos 组件中维护一个森林对象(FOREST)

森林对象由不同类型的日志树组合而成,并提供对外的接口进行日志的打印。

每种类型的树都可以通过种植操作来把自己添加到森林对象中,或者通过移除操作从森林对象中删除,从而实现该类型日志记录的开启和关闭。
private static final List FOREST = new ArrayList<>();

(2)种树

调用 plant() 方法,把 Tree 实例添加进 FOREST 里面 可以种植一棵树,也可以种植多棵树。这里以种一棵树为例。

可以看到,树的种植是在 plant() 静态方法的 synchronized 同步代码块中进行的。

具体流程是先将树对象添加到 FOREST 列表中,然后将日志树保存到 forestAsArray 数组中(将树种植到森林中)。

需要注意的是,如果树为空,则抛出空指针异常的错误;如果开发者手动种植灵魂之树(TREE_OF_SOULS),Timber_ohos 将会抛出非法数据异常。
public static void plant(@NotNull Tree tree) {
if (tree == null) {
throw new NullPointerException("tree == null");
}
if (tree == TREE_OF_SOULS) {
throw new IllegalArgumentException("Cannot plant Timber into itself.");
}
synchronized (FOREST) {
FOREST.add(tree);
forestAsArray = FOREST.toArray(new Tree[FOREST.size()]);
}
}

(3)移除 Tree 实例

同样的,树的移除也是在静态方法 uproot() 中的 synchronized 同步代码块中进行的。

如果没有该树可以移除,则 Timber_ohos 组件将抛出一个非法数据异常;反之,Timber_ohos 组件将根据移除该树后的 FOREST 列表生成新的 forestAsArray 数组。
public static void uproot(@NotNull Tree tree) {
synchronized (FOREST) {
if (!FOREST.remove(tree)) {
throw new IllegalArgumentException("Cannot uproot tree which is not planted: " + tree);
}
forestAsArray = FOREST.toArray(new Tree[FOREST.size()]);
}
}

(4)清除森林里面全部的 Tree 实例

移除森林里所有的 Tree 实例,首先使用 FOREST 的 clear() 方法清除所有的 Tree 实例,将会自动生成一个对应的新的 Tree 数组,而 forestAsArray 就是这个数组的引用。因此 forestAsArray 数组被设置为空数组。
public static void uprootAll() {
synchronized (FOREST) {
FOREST.clear();
forestAsArray = TREE_ARRAY_EMPTY;
}
}

(5) 灵魂之树(TREE_OF_SOULS)

估计很多同学好奇上述 TREE_OF_SOULS。代码实现中,在这里运用的是经典设计模式中的代理模式。

TREE_OF_SOULS 本质上是一个代理对象,森林中所有其他普通的树对象都是被代理对象,代理对象通过 for 循环来依次调用被代理对象的同名方法,从而实现不同类型的日志记录。

如下所示:
private static final Tree TREE_OF_SOULS = new Tree() {
@Override public void v(String message, Object... args) {
Tree[] forest = forestAsArray;
for (Tree tree : forest) {
tree.v(message, args);
}
}

②核心算法(prepareLog)

Timber_ohos 组件的日志记录功能的核心算法在抽象类 Tree 的私有化 prepareLog() 方法中,该方法接收四个参数,如图 4 所示:

来源:鸿蒙技术社区

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
红包 63 收藏 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
那片海
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区