当前位置:   article > 正文

小米便签源码精度_小米便签代码注释报告

小米便签代码注释报告

目录

一、基于AndroidStudio配置SonarLint

二、顺序图

2.1  概念

2.2  顺序图元素

2.3 顺序图

三、类图

3.1 ui里的继承类间关系​编辑

3.2 ui里的实现类间关系​编辑

3.3 data的类之间的调用关系图​编辑

3.4 gtask的类之间的调用关系图​编辑

四、精读部分的代码标注

4.1 data包

4.2 Gtask包​编辑

4.3 Tool

4.4 model.Note


一、基于AndroidStudio配置SonarLint

1.首先从SonarQube官网https://www.sonarsource.com/products/sonarqube/上下载SonarQube软件包。(这边下载的是8.9.10版本)

2.解压后运行bin\Window-x86-64目录下的StartSonar.bat文件启动SonarQube服务器(本机为Windows64位操作系统)。

运行至出现如下图输出时表示服务器已经建立:

3.访问http://localhost:9000并使用账户admin进行登陆,成功后即连接上SonarQube服务器。

输入账号密码后,进入如下图的界面:

点击创建项目,添加项目密钥:

生成令牌:

4.为了方便在本地的AndroidStudio中进行代码质量分析,下一步在AndroidStudio中配置SonarLint插件,该插件可以按照SonarQube中的规则对代码进行分析。

选择Settings中的Plugins搜索SonarLint插件进行下载:

绑定SonarQube:

选择Settings中的Tools的SonarLint,点击+号,绑定服务器:

点击下一步,可以选择Token方式登录或者用户密码的方式登录,输入Token或是账号密码即可:(这里选择账号密码)

配置本地端和服务端建立远端关联:

Android App构建脚本配置

在工程的build.gradle添加以下语句

maven {url "https://plugins.gradle.org/m2/"}
classpath "org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.0"


如下图:

在App的build.gradle添加以下语句

apply plugin: 'org.sonarqube'

sonarqube {

    properties {

        //Sonar服务器地址

        property "sonar.host.url", "*****************************"

        //Token模式

        property "sonar.login","**********************************"

        //账号密码模式

        //property "sonar.login","*******"

        //property "sonar.password","******"

        property "sonar.sourceEncoding", "UTF-8"

        property "sonar.projectKey", "Android_DuoApp"

        property "sonar.projectName", project.name

        //需要扫描的上传检测代码的模块,可以选择也可以配置哪一些需要或者不需要上传的模块(这里指APP模块下面的java包里面的全部)

        property "sonar.sources", "src/main/java"

        property "sonar.projectVersion", project.version

}}

如下图:

执行扫描并且上传分析

在终端使用命令./gradlew sonarqube:

build成功:

build成功之后就可以检查服务器端:

二、顺序图

2.1  概念

述参与者或子系统之间自上而下(时间维度)的交互。交互主要通过对象之间发送消息来实现。顺序图也可以用来展示出用例图的行为顺序,当参与者执行/触发一个用例时,都会有一条消息从触发者发送给接收者,从而引起状态转换。因为顺序图是按照时间顺序现实对象之间的交互,所以顺序图只能应用于顺序逻辑中,对于并发、异步等场景显得无能为力。

2.2  顺序图元素

顺序图有四部分:参与者/对象、生命周期线、激活期和消息。

2.3 顺序图

三、类图

3.1 ui里的继承类间关系

3.2 ui里的实现类间关系

3.3 data的类之间的调用关系图

3.4 gtask的类之间的调用关系图

四、精读部分的代码标注

4.1 data包

  1. contact.java  ( 获取联系人信息)

用于从Android设备上的联系人数据库中获取特定电话号码对应联系人姓名的Java类

这段代码的时间复杂度主要取决于数据库查询操作的效率假设查询操作的平均时间复杂度为O(n)n为数据库中联系人的数量,那么整体的时间复杂度也可以认为是O(n)。

2.  Notes.java (定义一些常量和标识符)

这个Notes类主要是一个常量类,定义了一些常量,这里有用于定义与笔记相关的各种常量和标识符这些常量使代码更加清晰、易于维护,并提高了代码的可读性以及可重用性

1) NotesDatabaseHelper.java (用于管理便签应用的数据库)

NotesDatabaseHelper类是一个用于管理SQLite数据库的Android帮助类这个类继承自SQLiteOpenHelper,它提供了创建和管理数据库的方法

3)NotesProvider.java (用于向数据库提供各种功能(增,删,改,查))

NotesProvider用于管理应用程序中的笔记数据

它首先定义了一个投影Projection,指定从数据库查询时应返回哪些列然后,定义SQL查询,用于从TABLE.NOT中检索满足特定条件的记录查询基NoteColumns.SNIPPET进行匹配用onCreate()方法确保正确处理上下文和生命周期事件

ContentProvider的实现用到了query(),insert(),update(),delete(),和getType()等方法

 query()方法首先函数定义,在初始化变量,使用switch语句根据URI的类型执行不同的查询

 insert()该方法接受一个Uri对象和一个ContentValues对象作为参数,Uri对象用于标识要插入数据的表,而ContentValues对象则包含要插入的实际数据。

其是向数据库插入数据并返回新URI的方法,从逻辑上看,时间复杂度可以认为是O(1)

delete()

  用于从SQLite数据库中删除数据该方法接受三个参数:一个Uri对象用于标识要删除的数据的位置一个selection字符串用于定义删除数据的条件以及一个selectionArgs字符串数组用于提供selection字符串中所需的参数值。

URI_DATA:删除DATA表中的数据。

URI_DATA_ITEM:根据提供的ID删除DATA表中的数据。

default:如果URI不匹配任何已知的类型,则抛出IllegalArgumentException异常。

update()

  update方法用于更新数据库中的数据。

4.2 Gtask包

gtask.data

  1. MetaData.java (用于管理任务的元数据 )

处理与任务相关的元数据而设计的。它有一个私有变量mRelatedGid来存储相关的ID,并提供了设置和获取这个ID的方法

    2. Node.java  (各种数据对象)

Node类是一个抽象类,定义了一个可以同步的数据节点的基本结构和行为这个类包含了一些表示节点属性和状态的成员变量,以及一些抽象方法和普通方法,用于操作这些属性和状态

    3.SqlData.java   (处理数据库的数据)

    4.SqlNote.java   (处理数据库的便签数据)

用于处理与笔记相关的数据库操作的工具类它定义了一些常量来简化数据库查询和日志记录,并可能包含一些方法来执行实际的数据库操作

PROJECTION_NOTE:一个字符串数组,包含了从NoteColumns类中引用的列名这些列名对应于数据库中的字段,用于指定数据库查询应该返回哪些列。

接下来构造了三个函数:

1)第一个构造函数:public SqlNote(Context context)用于创建一个新的笔记对象。

2)第二个构造函数:public SqlNote(Context context, Cursor c)用于从一个Cursor对象加载笔记数据。

3)第三个构造函数:public SqlNote(Context context, long id),用于根据给定的ID从数据库加载笔记数据。

        涉及到三个私有方法:loadFromCursor(long id)loadFromCursor(Cursor c) 和 loadDataContent()

    

loadFromCursor(Cursor c)这个方法接收一个Cursor对象作为参数,并从该Cursor中读取笔记数据

公共方法setContent目的是从传入的JSONObject中解析和设置内容

公共方法getContent,它返回一个JSONObject根据给定的笔记类型和其他相关属性(如ID、日期等)来构建一个JSON对象如果mTypeNotes.TYPE_NOTE,则还会包括一个数据列表如果在创建或处理JSON对象时发生错误,该方法将返回null

setParentId(long id)用于处理某种形式的笔记数据的创建、更新和检索提供了设置和获取笔记字段的方法,以及提交更改到数据库的方法

5. Task.java  (表示任务对象)

该类继承自Node

getCreateAction方法创建动作所需信息的 JSON 对象这个对象可能用于与服务器通信,以创建一个新的任务通过使用try-catch块和适当的异常处理,代码确保了即使在生成 JSON 对象时发生错误,也能提供有用的错误信息

getUpdateAction(int actionId)方法根据给定的actionId创建一个包含任务更新信息的JSONObject。

setContentByRemoteJSON(JSONObject js)从一个远程传入的JSONObject中设置任务的内容。

getSyncAction的Java方法,该方法接受一个Cursor对象c作为参数,并返回一个整型SYNC_ACTION_*常量,表示同步操作的类型。

时间复杂度主要取决于Cursor对象c的列访问操作和一系列的条件判断在最佳情况下,所有条件都不满足,代码将直接返回,时间复杂度为O(1)在最坏情况下,代码将执行所有的条件判断,但由于每个条件判断都是独立的,并且不依赖于输入数据的规模,因此整体时间复杂度仍为O(1)

    6.TaskList.java   (表示任务列表对象)

TaskList也是继承自Node

getCreateAction方法用于生成一个描述创建新任务列表的JSON对象,用于与服务器通信或进行其他需要JSON表示的任务列表创建操作

getUpdateAction(int actionId) 根据提供的actionId生成一个包含更新操作的JSONObject。

setContentByRemoteJSON(JSONObject js)从传入的JSONObject中提取数据并设置到当前对象中。

setContentByLocalJSON(JSONObject js)方法从JSON对象中读取信息并设置内容,getLocalJSONFromContent()方法则从当前内容生成一个JSON对象

removeChildTask方法从列表中移除一个指定的Task对象moveChildTask(Task task, int index) 方法用于列表中移动任务,findChildTaskByGid(String gid) 方法

用于根据全局唯一标识符查找任务。

getChildTaskIndex(Task task) getChildTaskByIndex(int index)  getChilTaskByGid(String gid)  getChildTaskList() setIndex(int index)   getIndex()方法共同构成了一个处理Task对象集合的实用工具集,提供了查找、获取和设置与Task对象相关的索引和属性的功能

  gtask.exception

  1.  ActionFailureException.java(支持小米便签运行过程中的运行异常处理)

类继承自RuntimeException,ActionFailureException类可能用于表示在执行某个操作或任务时发生的失败由于它继承自RuntimeException,这意味着它通常表示编程错误,而不是应用程序应该尝试捕获的异常情况,当在代码中遇到无法恢复的错误时,可以抛出此异常。

     2. NetworkFailureException.java (支持小米便签运行过程中的网络异常处理)

继承于Exception类,NetworkFailureException类是一个自定义异常类,用于表示网络请求失败的情况,它提供了三个构造函数,可以根据需要提供不同级别的错误信息因为其继承自Exception所以检查型异常,需要在代码中适当处理通过提供详细的错误信息,NetworkFailureException可以帮助开发者更好地理解和处理网络请求失败的情况。

     gtask.remote

  1. GTaskASyncTask.java(实现GTask的异步操作过程)
  2. GTaskClient.java(现GTASK的登录操作,进行GTASK任务的创建,创建任务列表,从网络上获取任务和任务列表的内容)

login方法的用于处理用户的登录逻辑 UI 交互。

tryToLoginGtask的方法,它的主要目的是尝试使用提供的authToken登录到Gtask如果登录失败,它会尝试刷新或重新获取authToken并再次尝试登录。

createHttpPost()方法创建一个新的 HTTP POST 请求,并设置了其 URL 和两个请求头:Content-Type 和 AT然后,它返回这个 HTTP POST 请求对象,以便其他方法可以使用它来发送请求。

getResponseContent(HttpEntity entity) 方法这个方法读取 HTTP 响应的内容,并返回其内容作为字符串。

postRequest()方法用户已登录的情况下,发送一个包含指定JSON对象的HTTP POST请求到服务器,并返回从服务器响应中解析出的JSON对象

  3. GTaskManager.java (实现本地同步和远端同步等方法)

mInstance:用于实现单例模式的静态成员变量。

mActivity和mContext:分别用于存储与Activity和Context相关的对象,用于访问应用的各种资源和功能。

mContentResolver:ContentResolver对象,用于访问Android内容提供者提供的数据。

mSyncing和mCancelled:分别表示当前是否正在同步和是否已取消同步的布尔变量。

mGTaskListHashMap、mGTaskHashMap、mMetaHashMap:这些HashMap用于存储不同类型的对象(如TaskList、Node和MetaData),键通常是字符串,而值是对应的对象。

mMetaList:一个TaskList对象,用于存储元数据。

mLocalDeleteIdMap:一个HashSet,用于存储要删除的ID。

mGidToNid和mNidToGid:两个HashMap,用于建立全局ID和节点ID之间的映射关系。

上面公共sync()方法是与 Google Task 服务进行同步它首先检查同步是否正在进行,然后初始化所需的变量,接着执行同步操作,并在过程中处理可能出现的异常无论同步是否成功,它都会执行一些清理工作,并确保返回适当的同步状态码

私有方法initGTaskList(),它的主要功能是初始化一个任务列表

n个任务列表中有m个任务,那么整个操作将执行n * m次基本操作所以时间复杂度是O(n * m)

syncContent的私有方法,它的目的是同步内容主要处理两种类型的笔记同步:一是本地已删除但仍在垃圾桶中的笔记,其次是数据库中存在但不在垃圾桶中的笔记。

首先处理垃圾桶中的记录,然后同步文件夹,最后处理数据库中的笔记记录,根据是否在垃圾桶中决定执行不同的同步操作通过不同的哈希映射来维护记录之间的关联关系,以便后续的同步操作

 syncFolder的私有方法,用于同步文件夹它主要处理两种类型的文件夹:根文件夹和通话记录文件夹它通过与内容提供者的交互获取文件夹信息,并根据这些信息执行相应的同步操作代码采用了良好的错误处理和资源管理实践,确保了稳定性和效率。

   GTaskSyncService.java (一段不定的时间运行在后台,不和用户交互的应用组件

这个服务主要用于同步任务Google 任务主要功能是响应两种类型的请求:开始同步和取消同步。当收到开始同步的请求时,它会创建一个新的异步任务并开始执行;当收到取消同步的请求时,它会尝试取消正在进行的同步任务。服务还通过广播来通知其他组件同步的状态和进度

4.3 Tool

    1.BackupUtils

这段代码的主要功能是将指定文件夹(由folderId标识)下的所有便签(Notes)导出到文本格式,并输出到提供的PrintStream对象ps中。导出内容包括每个便签的最后修改日期以及便签的详细内容。代码实现思路是基于Android的内容提供者(ContentProvider)机制,通过ContentResolver查询特定条件下的数据。在查询结果集上,代码通过遍历Cursor对象来逐条处理便签记录。对于每条记录,代码首先提取所需的信息(如最后修改日期和便签ID),然后调用其他方法(如exportNoteToText)来导出文本

2. BackupUtils

这段代码定义了一个batchDeleteNotes方法,用于批量删除多个便签(Notes)。它接受一个ContentResolver对象和一个包含要删除的便签ID的HashSet作为参数。方法首先检查传入的ID集合是否为空,如果为空或传入null,则记录日志并返回true(虽然这里返回true可能并不合适,因为实际上没有执行任何删除操作)。接下来,方法遍历ID集合,并为每个ID创建一个删除操作,这些操作被添加到operationList列表中。在遍历过程中,如果某个ID等于系统根文件夹的ID(Notes.ID_ROOT_FOLDER),则记录一条错误日志并跳过该ID。最后,方法尝试使用ContentResolverapplyBatch方法执行这些批量删除操作,并根据执行结果返回相应的布尔值。该方法时间复杂度为O(n), 空间复杂度是O(n)。

4.4 model.Note

 1. Note.java

这段代码的主要功能是在数据库中创建一条新的便签记录,并返回这条新记录的ID。它首先构建了一个ContentValues对象来存储新便签的各项属性(如创建时间、修改时间、类型、本地修改标记和父文件夹ID),然后通过ContentResolverinsert方法将这条记录插入到数据库中,并从返回的Uri对象中提取新记录的ID。代码的实现思路是遵循Android的数据存储和访问机制。首先,它构建了一个包含新便签数据的ContentValues对象。然后,通过ContentResolver将这些数据插入到数据库中,并获取一个表示新插入数据的Uri对象。接着,从Uri中提取新便签的ID。在整个过程中,代码还进行了必要的异常处理和ID有效性检查。这段代码没有涉及复杂的算法或数据结构,复杂度较低。

这段代码的主要功能是将文本数据(以键值对的形式存储在mTextDataValues中)与特定的便签ID(noteId)关联起来,并将这些数据保存到数据库中。如果mTextDataId为0,说明这是新的数据,需要插入一条新记录;如果mTextDataId不为0,说明已经存在对应的数据库记录,需要更新这条记录。实现思路基于Android的内容提供者(ContentProvider)机制。它首先判断是否需要插入新记录或更新现有记录,然后根据情况执行相应的数据库操作。在插入新记录时,它使用了ContentResolverinsert方法;在更新记录时,它使用了ContentProviderOperation来构建批量操作。

2.WorkingNote.java

这段代码的主要功能是加载指定ID的笔记的详细数据。它使用Android的内容解析器(ContentResolver)查询具有特定ID的笔记数据,并根据数据的MIME类型进行处理,以提取出不同类型的笔记数据(如文本内容、模式、以及其他数据ID等)。代码实现思路基于Android的内容提供者(ContentProvider)机制。通过ContentResolver发起查询请求,并使用Cursor遍历查询结果。根据每条记录的MIME类型,代码执行不同的逻辑分支以处理不同类型的笔记数据。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/449552
推荐阅读
相关标签
  

闽ICP备14008679号