From 1954950b7b4c1b3f15ac0ed70c4c7429349e3a3c Mon Sep 17 00:00:00 2001 From: XJS <2913789949@qq.com> Date: Thu, 17 Oct 2024 20:59:19 +0800 Subject: [PATCH 1/2] 10.17-xingjiasen --- README.md | 1 - ...小米便签开源代码的泛读报告.docx | Bin 16698 -> 0 bytes ...签开源代码的质量分析报告 .docx | Bin 13911 -> 0 bytes 3 files changed, 1 deletion(-) delete mode 100644 README.md delete mode 100644 doc/小米便签开源代码的泛读报告.docx delete mode 100644 doc/小米便签开源代码的质量分析报告 .docx diff --git a/README.md b/README.md deleted file mode 100644 index ec1f60c..0000000 --- a/README.md +++ /dev/null @@ -1 +0,0 @@ -huyunfei \ No newline at end of file diff --git a/doc/小米便签开源代码的泛读报告.docx b/doc/小米便签开源代码的泛读报告.docx deleted file mode 100644 index 92cdf698ed0aae8d6f97df93d97d27e6fe08e660..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16698 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 F{{gUsbC>`C diff --git a/doc/小米便签开源代码的质量分析报告 .docx b/doc/小米便签开源代码的质量分析报告 .docx deleted file mode 100644 index 45f911a6901431655901987f1bdf9f2d53d75f8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13911 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 From bd8d18a546c290db2ddbae951d715cb34870d9d3 Mon Sep 17 00:00:00 2001 From: XJS <2913789949@qq.com> Date: Wed, 25 Dec 2024 15:52:42 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E9=82=A2=E5=8A=A0=E6=A3=AE=20-gtask=20data?= =?UTF-8?q?=E5=8C=85exception=E5=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../net/micode/notes/gtask/data/MetaData.java | 32 +++++-- .../src/net/micode/notes/gtask/data/Node.java | 26 ++++- .../net/micode/notes/gtask/data/SqlData.java | 89 ++++++++++++++--- .../net/micode/notes/gtask/data/SqlNote.java | 95 +++++++++++-------- .../src/net/micode/notes/gtask/data/Task.java | 95 ++++++++++++------- .../net/micode/notes/gtask/data/TaskList.java | 79 ++++++++++----- .../exception/ActionFailureException.java | 6 +- .../exception/NetworkFailureException.java | 5 + 8 files changed, 307 insertions(+), 120 deletions(-) diff --git a/src/Notes-master/src/net/micode/notes/gtask/data/MetaData.java b/src/Notes-master/src/net/micode/notes/gtask/data/MetaData.java index 3a2050b..b44d477 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/data/MetaData.java +++ b/src/Notes-master/src/net/micode/notes/gtask/data/MetaData.java @@ -14,66 +14,86 @@ * limitations under the License. */ -package net.micode.notes.gtask.data; +package net.micode.notes.gtask.data;// 该类所在的包,用于组织代码结构,可能与gtask数据相关 import android.database.Cursor; import android.util.Log; -import net.micode.notes.tool.GTaskStringUtils; +import net.micode.notes.tool.GTaskStringUtils;// 自定义的工具类,用于处理与gtask相关的字符串操作 import org.json.JSONException; import org.json.JSONObject; - +// MetaData类继承自Task类(假设Task类是一个基类,提供了一些通用的任务相关功能) public class MetaData extends Task { + // 定义一个常量TAG,用于在日志记录中标识该类,值为类的简单名称 private final static String TAG = MetaData.class.getSimpleName(); - + // 用于存储相关的gid(可能是与gtask相关的唯一标识符) private String mRelatedGid = null; + // 设置元数据的方法,接受一个gid字符串和一个JSONObject类型的元数据信息 public void setMeta(String gid, JSONObject metaInfo) { try { + // 尝试将gid放入元数据信息的指定字段(假设GTaskStringUtils.META_HEAD_GTASK_ID是一个常量,表示在JSONObject中存储gid的键) metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); } catch (JSONException e) { + // 如果在放入gid时发生JSON异常,记录错误日志,提示无法放入相关gid Log.e(TAG, "failed to put related gid"); } + // 将元数据信息转换为字符串并设置为笔记内容(假设Task类中有setNotes方法用于设置笔记内容) setNotes(metaInfo.toString()); + // 设置名称为指定的常量(假设GTaskStringUtils.META_NOTE_NAME是一个常量,表示元数据的名称) setName(GTaskStringUtils.META_NOTE_NAME); } - + // 获取相关gid的方法 public String getRelatedGid() { return mRelatedGid; } + // 重写isWorthSaving方法(假设该方法在Task类中定义,用于判断是否值得保存) + // 判断依据是笔记内容是否不为空 @Override public boolean isWorthSaving() { return getNotes() != null; } + // 重写setContentByRemoteJSON方法(假设该方法在Task类中定义,用于根据远程JSON数据设置内容) @Override public void setContentByRemoteJSON(JSONObject js) { + // 先调用父类的setContentByRemoteJSON方法 super.setContentByRemoteJSON(js); if (getNotes() != null) { try { + // 从笔记内容创建一个新的JSONObject(去除首尾空格后) JSONObject metaInfo = new JSONObject(getNotes().trim()); + // 从元数据信息中获取相关gid并赋值给mRelatedGid + mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); } catch (JSONException e) { + // 如果获取相关gid时发生JSON异常,记录警告日志,提示无法获取相关gid,并将mRelatedGid设置为null Log.w(TAG, "failed to get related gid"); mRelatedGid = null; } } } + // 重写setContentByLocalJSON方法(假设该方法在Task类中定义,用于根据本地JSON数据设置内容) + // 这里明确表示该方法不应该被调用,如果被调用则抛出IllegalAccessError异常,并给出提示信息 @Override public void setContentByLocalJSON(JSONObject js) { // this function should not be called throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); } + // 重写getLocalJSONFromContent方法(假设该方法在Task类中定义,用于从内容获取本地JSON数据) + // 这里明确表示该方法不应该被调用,如果被调用则抛出IllegalAccessError异常,并给出提示信息 @Override public JSONObject getLocalJSONFromContent() { throw new IllegalAccessError("MetaData:getLocalJSONFromContent should not be called"); } - + + // 重写getSyncAction方法(假设该方法在Task类中定义,用于获取同步操作相关信息) + // 这里明确表示该方法不应该被调用,如果被调用则抛出IllegalAccessError异常,并给出提示信息 @Override public int getSyncAction(Cursor c) { throw new IllegalAccessError("MetaData:getSyncAction should not be called"); diff --git a/src/Notes-master/src/net/micode/notes/gtask/data/Node.java b/src/Notes-master/src/net/micode/notes/gtask/data/Node.java index 63950e0..ca56943 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/data/Node.java +++ b/src/Notes-master/src/net/micode/notes/gtask/data/Node.java @@ -20,7 +20,9 @@ import android.database.Cursor; import org.json.JSONObject; +// 定义一个抽象类Node,可能是用于表示某种数据节点,作为其他具体节点类的基类 public abstract class Node { + // 定义一系列常量,表示同步操作的类型 public static final int SYNC_ACTION_NONE = 0; public static final int SYNC_ACTION_ADD_REMOTE = 1; @@ -39,14 +41,16 @@ public abstract class Node { public static final int SYNC_ACTION_ERROR = 8; + // 用于存储节点的唯一标识符(可能是全局唯一的) private String mGid; - + // 用于存储节点的名称 private String mName; - + // 用于存储节点的最后修改时间 private long mLastModified; - + // 用于标记节点是否已被删除 private boolean mDeleted; + // 无参构造函数,初始化节点的属性 public Node() { mGid = null; mName = ""; @@ -54,46 +58,62 @@ public abstract class Node { mDeleted = false; } + // 抽象方法,用于获取创建操作的JSONObject表示,具体实现由子类提供 + // 参数actionId可能用于指定创建操作的具体类型或相关参数 public abstract JSONObject getCreateAction(int actionId); + // 抽象方法,用于获取更新操作的JSONObject表示,具体实现由子类提供 + // 参数actionId可能用于指定更新操作的具体类型或相关参数 public abstract JSONObject getUpdateAction(int actionId); + // 抽象方法,用于根据远程JSON数据设置节点内容,具体实现由子类提供 public abstract void setContentByRemoteJSON(JSONObject js); + // 抽象方法,用于根据本地JSON数据设置节点内容,具体实现由子类提供 public abstract void setContentByLocalJSON(JSONObject js); + // 抽象方法,用于从节点内容获取本地JSON数据,具体实现由子类提供 public abstract JSONObject getLocalJSONFromContent(); + // 抽象方法,用于根据数据库游标获取节点的同步操作类型,具体实现由子类提供 public abstract int getSyncAction(Cursor c); + // 设置节点的唯一标识符 public void setGid(String gid) { this.mGid = gid; } + // 设置节点的名称 public void setName(String name) { this.mName = name; } + // 设置节点的最后修改时间 public void setLastModified(long lastModified) { this.mLastModified = lastModified; } + // 设置节点的删除标记 public void setDeleted(boolean deleted) { this.mDeleted = deleted; } + // 获取节点的唯一标识符 public String getGid() { return this.mGid; } + // 获取节点的名称 public String getName() { return this.mName; } + // 获取节点的最后修改时间 public long getLastModified() { return this.mLastModified; } + // 获取节点的删除标记 public boolean getDeleted() { return this.mDeleted; } diff --git a/src/Notes-master/src/net/micode/notes/gtask/data/SqlData.java b/src/Notes-master/src/net/micode/notes/gtask/data/SqlData.java index d3ec3be..67c2dc6 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/data/SqlData.java +++ b/src/Notes-master/src/net/micode/notes/gtask/data/SqlData.java @@ -35,137 +35,195 @@ import org.json.JSONException; import org.json.JSONObject; +// SqlData类,可能用于处理与SQL数据库相关的数据操作,与gtask数据相关 public class SqlData { + // 定义一个常量TAG,用于在日志记录中标识该类,值为类的简单名称 private static final String TAG = SqlData.class.getSimpleName(); - + // 定义一个无效的ID值,用于初始化或表示无效的情况 private static final int INVALID_ID = -99999; + // 定义一个字符串数组,用于指定从数据库查询数据时的投影列(即要查询的列) public static final String[] PROJECTION_DATA = new String[] { DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.DATA3 }; + // 定义常量,表示在投影列数组中ID列的索引 public static final int DATA_ID_COLUMN = 0; - + // 定义常量,表示在投影列数组中MIME_TYPE列的索引 public static final int DATA_MIME_TYPE_COLUMN = 1; - + // 定义常量,表示在投影列数组中CONTENT列的索引 public static final int DATA_CONTENT_COLUMN = 2; - + // 定义常量,表示在投影列数组中DATA1列的索引(假设是CONTENT相关的数据1列) public static final int DATA_CONTENT_DATA_1_COLUMN = 3; - + // 定义常量,表示在投影列数组中DATA3列的索引(假设是CONTENT相关的数据3列) public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + // 用于与内容提供器交互,执行数据库操作 private ContentResolver mContentResolver; - + // 标记是否是创建操作 private boolean mIsCreate; - + // 存储数据的ID private long mDataId; - + // 存储数据的MIME类型 private String mDataMimeType; - + // 存储数据的内容 private String mDataContent; - + // 存储与数据内容相关的数据1(具体含义根据业务而定) private long mDataContentData1; - + // 存储与数据内容相关的数据3(具体含义根据业务而定) private String mDataContentData3; - + // 用于存储要更新的数据值 private ContentValues mDiffDataValues; + // 构造函数,用于创建一个新的SqlData实例,通常用于插入新数据 public SqlData(Context context) { + // 获取上下文的内容解析器,用于与内容提供器交互 mContentResolver = context.getContentResolver(); + // 标记为创建操作 mIsCreate = true; + // 初始化数据ID为无效值 mDataId = INVALID_ID; + // 初始化MIME类型为默认值(假设DataConstants.NOTE是一个常量,表示笔记类型的MIME类型) mDataMimeType = DataConstants.NOTE; + // 初始化数据内容为空字符串 mDataContent = ""; + // 初始化数据内容相关的数据1为0 mDataContentData1 = 0; + // 初始化数据内容相关的数据3为空字符串 mDataContentData3 = ""; + // 创建一个新的ContentValues实例,用于存储要更新的数据 mDiffDataValues = new ContentValues(); } - + // 构造函数,用于根据数据库游标创建一个SqlData实例,通常用于查询现有数据 public SqlData(Context context, Cursor c) { mContentResolver = context.getContentResolver(); + // 标记为非创建操作(即查询或更新现有数据) mIsCreate = false; + // 从游标加载数据到对象属性中 loadFromCursor(c); mDiffDataValues = new ContentValues(); } + // 从游标加载数据到对象属性的私有方法 private void loadFromCursor(Cursor c) { + // 从游标获取ID列的值并赋值给mDataId mDataId = c.getLong(DATA_ID_COLUMN); + // 从游标获取MIME_TYPE列的值并赋值给mDataMimeType mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); + // 从游标获取CONTENT列的值并赋值给mDataContent mDataContent = c.getString(DATA_CONTENT_COLUMN); + // 从游标获取CONTENT相关的数据1列的值并赋值给mDataContentData1 mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); + // 从游标获取CONTENT相关的数据3列的值并赋值给mDataContentData3 mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); } + // 设置数据内容的方法,接受一个JSONObject作为参数 public void setContent(JSONObject js) throws JSONException { + // 从JSON对象获取ID值,如果不存在则使用无效ID long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; + // 如果是创建操作或者数据ID发生了变化,则将新的ID值放入要更新的ContentValues中 if (mIsCreate || mDataId != dataId) { mDiffDataValues.put(DataColumns.ID, dataId); } + // 更新数据ID mDataId = dataId; + // 从JSON对象获取MIME_TYPE值,如果不存在则使用默认的MIME类型 String dataMimeType = js.has(DataColumns.MIME_TYPE) ? js.getString(DataColumns.MIME_TYPE) : DataConstants.NOTE; + // 如果是创建操作或者MIME类型发生了变化,则将新的MIME类型放入要更新的ContentValues中 if (mIsCreate || !mDataMimeType.equals(dataMimeType)) { mDiffDataValues.put(DataColumns.MIME_TYPE, dataMimeType); } + + // 更新MIME类型 mDataMimeType = dataMimeType; + // 从JSON对象获取CONTENT值,如果不存在则使用空字符串 String dataContent = js.has(DataColumns.CONTENT) ? js.getString(DataColumns.CONTENT) : ""; + // 如果是创建操作或者数据内容发生了变化,则将新的内容放入要更新的ContentValues中 if (mIsCreate || !mDataContent.equals(dataContent)) { mDiffDataValues.put(DataColumns.CONTENT, dataContent); } + // 更新数据内容 mDataContent = dataContent; + // 从JSON对象获取CONTENT相关的数据1值,如果不存在则使用0 long dataContentData1 = js.has(DataColumns.DATA1) ? js.getLong(DataColumns.DATA1) : 0; + // 如果是创建操作或者数据内容相关的数据1发生了变化,则将新的值放入要更新的ContentValues中 if (mIsCreate || mDataContentData1 != dataContentData1) { mDiffDataValues.put(DataColumns.DATA1, dataContentData1); } + // 更新数据内容相关的数据1 mDataContentData1 = dataContentData1; + // 从JSON对象获取CONTENT相关的数据3值,如果不存在则使用空字符串 String dataContentData3 = js.has(DataColumns.DATA3) ? js.getString(DataColumns.DATA3) : ""; + // 如果是创建操作或者数据内容相关的数据3发生了变化,则将新的值放入要更新的ContentValues中 if (mIsCreate || !mDataContentData3.equals(dataContentData3)) { mDiffDataValues.put(DataColumns.DATA3, dataContentData3); } + // 更新数据内容相关的数据3 mDataContentData3 = dataContentData3; } + // 获取数据内容的方法,返回一个JSONObject public JSONObject getContent() throws JSONException { + // 如果是创建操作,记录错误日志并返回null,因为数据还未在数据库中创建 if (mIsCreate) { Log.e(TAG, "it seems that we haven't created this in database yet"); return null; } + // 创建一个新的JSONObject JSONObject js = new JSONObject(); + // 将数据ID放入JSON对象 js.put(DataColumns.ID, mDataId); + // 将MIME类型放入JSON对象 js.put(DataColumns.MIME_TYPE, mDataMimeType); + // 将数据内容放入JSON对象 js.put(DataColumns.CONTENT, mDataContent); + // 将数据内容相关的数据1放入JSON对象 js.put(DataColumns.DATA1, mDataContentData1); + // 将数据内容相关的数据3放入JSON对象 js.put(DataColumns.DATA3, mDataContentData3); return js; } + // 提交数据到数据库的方法,接受笔记ID、是否验证版本和版本号作为参数 public void commit(long noteId, boolean validateVersion, long version) { + // 如果是创建操作 if (mIsCreate) { + // 如果数据ID为无效值且要更新的ContentValues中包含ID列,则移除ID列(可能是因为插入操作不需要手动指定ID) if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { mDiffDataValues.remove(DataColumns.ID); } + // 将笔记ID放入要更新的ContentValues中 mDiffDataValues.put(DataColumns.NOTE_ID, noteId); + // 使用内容解析器插入数据到指定的URI(假设Notes.CONTENT_DATA_URI是一个常量,表示数据插入的URI) Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); try { + // 尝试从插入后的URI路径片段中获取插入数据的ID并赋值给mDataId mDataId = Long.valueOf(uri.getPathSegments().get(1)); } catch (NumberFormatException e) { + // 如果获取ID时发生数字格式异常,记录错误日志并抛出ActionFailureException异常,表示创建笔记失败 Log.e(TAG, "Get note id error :" + e.toString()); throw new ActionFailureException("create note failed"); } } else { + // 如果要更新的数据值不为空 if (mDiffDataValues.size() > 0) { int result = 0; + // 如果不验证版本 if (!validateVersion) { + // 使用内容解析器更新指定ID的数据(不进行版本验证) result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); } else { + // 使用内容解析器更新指定ID的数据,并根据版本号进行验证(假设NoteColumns.VERSION是一个常量,表示版本列) result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE @@ -173,16 +231,19 @@ public class SqlData { String.valueOf(noteId), String.valueOf(version) }); } + // 如果更新结果为0,表示没有进行更新,记录警告日志(可能是因为用户在同步时更新了笔记) if (result == 0) { Log.w(TAG, "there is no update. maybe user updates note when syncing"); } } } + // 清空要更新的数据值 mDiffDataValues.clear(); + // 标记为非创建操作 mIsCreate = false; } - + // 获取数据ID的方法 public long getId() { return mDataId; } diff --git a/src/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java b/src/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java index 79a4095..90a4764 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java +++ b/src/Notes-master/src/net/micode/notes/gtask/data/SqlNote.java @@ -37,12 +37,13 @@ import org.json.JSONObject; import java.util.ArrayList; - +// SqlNote类,可能用于处理与SQL数据库中笔记相关的数据操作,与gtask数据相关 public class SqlNote { + // 定义一个常量TAG,用于在日志记录中标识该类,值为类的简单名称 private static final String TAG = SqlNote.class.getSimpleName(); - +// 定义一个无效的ID值,用于初始化或表示无效的情况 private static final int INVALID_ID = -99999; - +// 定义一个字符串数组,用于指定从数据库查询笔记时的投影列(即要查询的列) public static final String[] PROJECTION_NOTE = new String[] { NoteColumns.ID, NoteColumns.ALERTED_DATE, NoteColumns.BG_COLOR_ID, NoteColumns.CREATED_DATE, NoteColumns.HAS_ATTACHMENT, NoteColumns.MODIFIED_DATE, @@ -51,83 +52,86 @@ public class SqlNote { NoteColumns.LOCAL_MODIFIED, NoteColumns.ORIGIN_PARENT_ID, NoteColumns.GTASK_ID, NoteColumns.VERSION }; - + // 定义常量,表示在投影列数组中ID列的索引 public static final int ID_COLUMN = 0; - + // 定义常量,表示在投影列数组中ALERTED_DATE列的索引 public static final int ALERTED_DATE_COLUMN = 1; - + // 定义常量,表示在投影列数组中BG_COLOR_ID列的索引 public static final int BG_COLOR_ID_COLUMN = 2; - + // 定义常量,表示在投影列数组中CREATED_DATE列的索引 public static final int CREATED_DATE_COLUMN = 3; - + // 定义常量,表示在投影列数组中HAS_ATTACHMENT列的索引 public static final int HAS_ATTACHMENT_COLUMN = 4; - + // 定义常量,表示在投影列数组中MODIFIED_DATE列的索引 public static final int MODIFIED_DATE_COLUMN = 5; - + // 定义常量,表示在投影列数组中NOTES_COUNT列的索引 public static final int NOTES_COUNT_COLUMN = 6; - + // 定义常量,表示在投影列数组中PARENT_ID列的索引 public static final int PARENT_ID_COLUMN = 7; - + // 定义常量,表示在投影列数组中SNIPPET列的索引 public static final int SNIPPET_COLUMN = 8; - + // 定义常量,表示在投影列数组中TYPE列的索引 public static final int TYPE_COLUMN = 9; - + // 定义常量,表示在投影列数组中WIDGET_ID列的索引 public static final int WIDGET_ID_COLUMN = 10; - + // 定义常量,表示在投影列数组中WIDGET_TYPE列的索引 public static final int WIDGET_TYPE_COLUMN = 11; - + // 定义常量,表示在投影列数组中SYNC_ID列的索引 public static final int SYNC_ID_COLUMN = 12; - + // 定义常量,表示在投影列数组中LOCAL_MODIFIED列的索引 public static final int LOCAL_MODIFIED_COLUMN = 13; - + // 定义常量,表示在投影列数组中ORIGIN_PARENT_ID列的索引 public static final int ORIGIN_PARENT_ID_COLUMN = 14; - + // 定义常量,表示在投影列数组中GTASK_ID列的索引 public static final int GTASK_ID_COLUMN = 15; - + // 定义常量,表示在投影列数组中VERSION列的索引 public static final int VERSION_COLUMN = 16; + // 上下文对象,用于获取系统资源和服务 private Context mContext; - + // 用于与内容提供器交互,执行数据库操作 private ContentResolver mContentResolver; - + // 标记是否是创建操作 private boolean mIsCreate; - + // 存储笔记的ID private long mId; - + // 存储笔记的提醒日期 private long mAlertDate; - + // 存储笔记的背景颜色ID private int mBgColorId; - + // 存储笔记的创建日期 private long mCreatedDate; - + // 存储笔记是否有附件(0或1表示) private int mHasAttachment; - + // 存储笔记的修改日期 private long mModifiedDate; - + // 存储笔记的父ID private long mParentId; - + // 存储笔记的摘要或片段内容 private String mSnippet; - + // 存储笔记的类型(如普通笔记、文件夹等类型,假设Notes.TYPE_NOTE等是常量表示不同类型) private int mType; - + // 存储笔记关联的小部件ID private int mWidgetId; - + // 存储笔记关联的小部件类型 private int mWidgetType; - + // 存储笔记的原始父ID(可能用于记录笔记的来源或初始父节点) private long mOriginParent; - + // 存储笔记的版本号 private long mVersion; - + // 用于存储要更新的笔记数据值 private ContentValues mDiffNoteValues; - + // 存储与笔记相关的数据列表(可能是笔记包含的数据内容,每个元素是SqlData类型) private ArrayList mDataList; + // 构造函数,用于创建一个新的SqlNote实例,通常用于插入新笔记 public SqlNote(Context context) { mContext = context; mContentResolver = context.getContentResolver(); mIsCreate = true; mId = INVALID_ID; mAlertDate = 0; + // 使用ResourceParser获取默认的背景颜色ID(假设ResourceParser类提供了相关方法) mBgColorId = ResourceParser.getDefaultBgId(context); mCreatedDate = System.currentTimeMillis(); mHasAttachment = 0; @@ -135,6 +139,7 @@ public class SqlNote { mParentId = 0; mSnippet = ""; mType = Notes.TYPE_NOTE; + // 使用无效的小部件ID初始化(假设AppWidgetManager.INVALID_APPWIDGET_ID是一个常量表示无效ID) mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; mWidgetType = Notes.TYPE_WIDGET_INVALIDE; mOriginParent = 0; @@ -143,17 +148,20 @@ public class SqlNote { mDataList = new ArrayList(); } + // 构造函数,用于根据数据库游标创建一个SqlNote实例,通常用于查询现有笔记 public SqlNote(Context context, Cursor c) { mContext = context; mContentResolver = context.getContentResolver(); mIsCreate = false; loadFromCursor(c); mDataList = new ArrayList(); + // 如果笔记类型是普通笔记,则加载数据内容(调用loadDataContent方法) if (mType == Notes.TYPE_NOTE) loadDataContent(); mDiffNoteValues = new ContentValues(); } + // 构造函数,用于根据指定的ID从数据库加载笔记数据创建一个SqlNote实例 public SqlNote(Context context, long id) { mContext = context; mContentResolver = context.getContentResolver(); @@ -166,15 +174,18 @@ public class SqlNote { } + // 从指定ID的游标加载笔记数据的私有方法 private void loadFromCursor(long id) { Cursor c = null; try { + // 使用内容解析器查询指定ID的笔记数据,投影列为PROJECTION_NOTE,查询条件为_id等于指定ID c = mContentResolver.query(Notes.CONTENT_NOTE_URI, PROJECTION_NOTE, "(_id=?)", new String[] { String.valueOf(id) }, null); if (c != null) { c.moveToNext(); + // 从游标加载数据到对象属性中 loadFromCursor(c); } else { Log.w(TAG, "loadFromCursor: cursor = null"); @@ -185,6 +196,7 @@ public class SqlNote { } } + // 从游标加载笔记数据到对象属性的私有方法 private void loadFromCursor(Cursor c) { mId = c.getLong(ID_COLUMN); mAlertDate = c.getLong(ALERTED_DATE_COLUMN); @@ -200,10 +212,12 @@ public class SqlNote { mVersion = c.getLong(VERSION_COLUMN); } + // 加载笔记数据内容的私有方法,将与笔记相关的数据加载到mDataList中 private void loadDataContent() { Cursor c = null; mDataList.clear(); try { + // 使用内容解析器查询与笔记相关的数据,投影列为SqlData.PROJECTION_DATA,查询条件为note_id等于笔记ID c = mContentResolver.query(Notes.CONTENT_DATA_URI, SqlData.PROJECTION_DATA, "(note_id=?)", new String[] { String.valueOf(mId) @@ -214,6 +228,7 @@ public class SqlNote { return; } while (c.moveToNext()) { + // 根据游标创建SqlData实例并添加到数据列表中 SqlData data = new SqlData(mContext, c); mDataList.add(data); } @@ -226,13 +241,16 @@ public class SqlNote { } } + // 设置笔记内容的方法,接受一个JSONObject作为参数 public boolean setContent(JSONObject js) { try { + // 从JSON对象获取笔记头部信息(假设GTaskStringUtils.META_HEAD_NOTE是一个常量表示笔记头部信息的键) JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); + // 如果笔记类型是系统类型,则记录警告日志,因为不能设置系统文件夹 if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) { Log.w(TAG, "cannot set system folder"); } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_FOLDER) { - // for folder we can only update the snnipet and type + // 如果是文件夹类型,只能更新摘要和类型 String snippet = note.has(NoteColumns.SNIPPET) ? note .getString(NoteColumns.SNIPPET) : ""; if (mIsCreate || !mSnippet.equals(snippet)) { @@ -247,6 +265,7 @@ public class SqlNote { } mType = type; } else if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_NOTE) { + // 如果是普通笔记类型 JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA); long id = note.has(NoteColumns.ID) ? note.getLong(NoteColumns.ID) : INVALID_ID; if (mIsCreate || mId != id) { diff --git a/src/Notes-master/src/net/micode/notes/gtask/data/Task.java b/src/Notes-master/src/net/micode/notes/gtask/data/Task.java index 6a19454..c95cdbb 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/data/Task.java +++ b/src/Notes-master/src/net/micode/notes/gtask/data/Task.java @@ -31,20 +31,22 @@ import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; - +// Task类,继承自Node类,可能用于表示任务相关的数据结构,与gtask数据相关 public class Task extends Node { + // 定义一个常量TAG,用于在日志记录中标识该类,值为类的简单名称 private static final String TAG = Task.class.getSimpleName(); - + // 标记任务是否已完成 private boolean mCompleted; - + // 存储任务的笔记内容 private String mNotes; - + // 存储任务的元数据信息(可能是与任务相关的额外信息,以JSONObject形式存储) private JSONObject mMetaInfo; - + // 存储任务的前一个兄弟任务(用于构建任务列表的顺序关系) private Task mPriorSibling; - + // 存储任务所属的父任务列表(表示任务的层级关系) private TaskList mParent; + // 构造函数,初始化任务对象的属性 public Task() { super(); mCompleted = false; @@ -54,47 +56,54 @@ public class Task extends Node { mMetaInfo = null; } + // 生成创建任务的JSON对象的方法,用于与外部系统(可能是gtask服务端)交互,指定创建任务的相关信息 public JSONObject getCreateAction(int actionId) { JSONObject js = new JSONObject(); try { - // action_type + // 设置操作类型为创建任务(假设GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE是一个常量表示创建操作类型) js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); - // action_id + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // index + // 设置任务在父任务列表中的索引(通过父任务列表获取) js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this)); - // entity_delta + // 创建任务实体的JSON对象 JSONObject entity = new JSONObject(); + // 设置任务名称 entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + // 设置任务创建者ID为null(可能在实际应用中需要根据真实情况设置) entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + // 设置任务实体类型为任务(假设GTaskStringUtils.GTASK_JSON_TYPE_TASK是一个常量表示任务类型) entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, GTaskStringUtils.GTASK_JSON_TYPE_TASK); + // 如果有笔记内容,则添加到任务实体中 if (getNotes() != null) { entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); } + // 将任务实体添加到操作JSON对象中 js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); - // parent_id + // 设置父任务ID(通过父任务列表获取) js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid()); - // dest_parent_type + // 设置目标父类型为组(假设GTaskStringUtils.GTASK_JSON_TYPE_GROUP是一个常量表示组类型) js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE, GTaskStringUtils.GTASK_JSON_TYPE_GROUP); - // list_id + // 设置列表ID(与父任务ID相同,可能在某些情况下需要不同的处理) js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid()); - // prior_sibling_id + // 如果有前一个兄弟任务,则设置前一个兄弟任务的ID if (mPriorSibling != null) { js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid()); } } catch (JSONException e) { + // 如果在创建JSON对象过程中发生异常,记录错误日志,打印堆栈跟踪,并抛出ActionFailureException异常,表示生成创建任务的JSON对象失败 Log.e(TAG, e.toString()); e.printStackTrace(); throw new ActionFailureException("fail to generate task-create jsonobject"); @@ -103,30 +112,36 @@ public class Task extends Node { return js; } + // 生成更新任务的JSON对象的方法,用于与外部系统(可能是gtask服务端)交互,指定更新任务的相关信息 public JSONObject getUpdateAction(int actionId) { JSONObject js = new JSONObject(); try { - // action_type + // 设置操作类型为更新任务(假设GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE是一个常量表示更新操作类型) js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); - // action_id + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // id + // 设置任务ID js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); - // entity_delta + // 创建任务实体的JSON对象 JSONObject entity = new JSONObject(); + // 设置任务名称 entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + // 如果有笔记内容,则添加到任务实体中 if (getNotes() != null) { entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes()); } + // 设置任务的删除标记 entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); + // 将任务实体添加到操作JSON对象中 js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); } catch (JSONException e) { + // 如果在创建JSON对象过程中发生异常,记录错误日志,打印堆栈跟踪,并抛出ActionFailureException异常,表示生成更新任务的JSON对象失败 Log.e(TAG, e.toString()); e.printStackTrace(); throw new ActionFailureException("fail to generate task-update jsonobject"); @@ -134,40 +149,41 @@ public class Task extends Node { return js; } - + // 根据远程JSON数据设置任务内容的方法,从远程获取的JSON数据中解析并设置任务的各种属性 public void setContentByRemoteJSON(JSONObject js) { if (js != null) { try { - // id + // 如果JSON对象中包含任务ID,则设置任务ID if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); } - // last_modified + // 如果JSON对象中包含最后修改时间,则设置最后修改时间 if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); } - // name + // 如果JSON对象中包含任务名称,则设置任务名称 if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); } - // notes + // 如果JSON对象中包含笔记内容,则设置笔记内容 if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) { setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES)); } - // deleted + // 如果JSON对象中包含删除标记,则设置删除标记 if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) { setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED)); } - // completed + // 如果JSON对象中包含完成标记,则设置完成标记 if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) { setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED)); } } catch (JSONException e) { + // 如果在解析JSON数据过程中发生异常,记录错误日志,打印堆栈跟踪,并抛出ActionFailureException异常,表示从JSON对象获取任务内容失败 Log.e(TAG, e.toString()); e.printStackTrace(); throw new ActionFailureException("fail to get task content from jsonobject"); @@ -175,6 +191,7 @@ public class Task extends Node { } } + // 根据本地JSON数据设置任务内容的方法,从本地存储的JSON数据中解析并设置任务的名称(根据特定的结构和条件) public void setContentByLocalJSON(JSONObject js) { if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE) || !js.has(GTaskStringUtils.META_HEAD_DATA)) { @@ -204,11 +221,12 @@ public class Task extends Node { } } + // 从任务内容生成本地JSON对象的方法,根据任务的当前状态(是否有元数据等)构建用于本地存储或传输的JSON对象 public JSONObject getLocalJSONFromContent() { String name = getName(); try { if (mMetaInfo == null) { - // new task created from web + // 如果元数据为空,表示新任务从网页创建 if (name == null) { Log.w(TAG, "the note seems to be an empty one"); return null; @@ -225,7 +243,7 @@ public class Task extends Node { js.put(GTaskStringUtils.META_HEAD_NOTE, note); return js; } else { - // synced task + // 如果有元数据,表示是已同步的任务 JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE); JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA); @@ -247,6 +265,7 @@ public class Task extends Node { } } + // 设置任务元数据信息的方法,接受一个MetaData对象,从其中获取笔记内容并尝试转换为JSONObject作为元数据 public void setMetaInfo(MetaData metaData) { if (metaData != null && metaData.getNotes() != null) { try { @@ -258,6 +277,7 @@ public class Task extends Node { } } + // 根据数据库游标获取任务的同步操作类型的方法,通过比较任务的各种属性(如元数据中的笔记ID、本地修改标记、gtask ID等)与数据库中的数据来确定同步操作类型 public int getSyncAction(Cursor c) { try { JSONObject noteInfo = null; @@ -275,29 +295,29 @@ public class Task extends Node { return SYNC_ACTION_UPDATE_LOCAL; } - // validate the note id now + // 验证笔记ID是否匹配 if (c.getLong(SqlNote.ID_COLUMN) != noteInfo.getLong(NoteColumns.ID)) { Log.w(TAG, "note id doesn't match"); return SYNC_ACTION_UPDATE_LOCAL; } if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { - // there is no local update + // 如果本地没有更新 if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // no update both side + // 双方都没有更新 return SYNC_ACTION_NONE; } else { - // apply remote to local + // 应用远程更新到本地 return SYNC_ACTION_UPDATE_LOCAL; } } else { - // validate gtask id + // 验证gtask ID是否匹配 if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) { Log.e(TAG, "gtask id doesn't match"); return SYNC_ACTION_ERROR; } if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // local modification only + // 只有本地修改 return SYNC_ACTION_UPDATE_REMOTE; } else { return SYNC_ACTION_UPDATE_CONFLICT; @@ -311,39 +331,48 @@ public class Task extends Node { return SYNC_ACTION_ERROR; } + // 判断任务是否值得保存的方法,根据任务是否有元数据、名称或笔记内容来确定 public boolean isWorthSaving() { return mMetaInfo != null || (getName() != null && getName().trim().length() > 0) || (getNotes() != null && getNotes().trim().length() > 0); } + // 设置任务完成标记的方法 public void setCompleted(boolean completed) { this.mCompleted = completed; } + // 设置任务笔记内容的方法 public void setNotes(String notes) { this.mNotes = notes; } + // 设置任务前一个兄弟任务的方法 public void setPriorSibling(Task priorSibling) { this.mPriorSibling = priorSibling; } + // 设置任务父任务列表的方法 public void setParent(TaskList parent) { this.mParent = parent; } + // 获取任务完成标记的方法 public boolean getCompleted() { return this.mCompleted; } + // 获取任务笔记内容的方法 public String getNotes() { return this.mNotes; } + // 获取任务前一个兄弟任务的方法 public Task getPriorSibling() { return this.mPriorSibling; } + // 获取任务父任务列表的方法 public TaskList getParent() { return this.mParent; } diff --git a/src/Notes-master/src/net/micode/notes/gtask/data/TaskList.java b/src/Notes-master/src/net/micode/notes/gtask/data/TaskList.java index 4ea21c5..7626659 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/data/TaskList.java +++ b/src/Notes-master/src/net/micode/notes/gtask/data/TaskList.java @@ -29,43 +29,51 @@ import org.json.JSONObject; import java.util.ArrayList; - +// TaskList类,继承自Node类,可能用于表示任务列表相关的数据结构,与gtask数据相关 public class TaskList extends Node { + // 定义一个常量TAG,用于在日志记录中标识该类,值为类的简单名称 private static final String TAG = TaskList.class.getSimpleName(); - + // 存储任务列表的索引(可能用于在某个父级结构中的排序或标识) private int mIndex; - + // 存储任务列表中的任务集合(使用ArrayList存储任务对象) private ArrayList mChildren; + // 构造函数,初始化任务列表对象的属性 public TaskList() { super(); mChildren = new ArrayList(); mIndex = 1; } + // 生成创建任务列表的JSON对象的方法,用于与外部系统(可能是gtask服务端)交互,指定创建任务列表的相关信息 public JSONObject getCreateAction(int actionId) { JSONObject js = new JSONObject(); try { - // action_type + // 设置操作类型为创建任务列表(假设GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE是一个常量表示创建操作类型) js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE); - // action_id + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // index + // 设置任务列表的索引 js.put(GTaskStringUtils.GTASK_JSON_INDEX, mIndex); - // entity_delta + // 创建任务列表实体的JSON对象 JSONObject entity = new JSONObject(); + // 设置任务列表名称 entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + // 设置任务列表创建者ID为null(可能在实际应用中需要根据真实情况设置) entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null"); + // 设置任务列表实体类型为组(假设GTaskStringUtils.GTASK_JSON_TYPE_GROUP是一个常量表示组类型) entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE, GTaskStringUtils.GTASK_JSON_TYPE_GROUP); + // 将任务列表实体添加到操作JSON对象中 js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); } catch (JSONException e) { + // 如果在创建JSON对象过程中发生异常,记录错误日志,打印堆栈跟踪,并抛出ActionFailureException异常,表示生成创建任务列表的JSON对象失败 Log.e(TAG, e.toString()); e.printStackTrace(); throw new ActionFailureException("fail to generate tasklist-create jsonobject"); @@ -74,27 +82,32 @@ public class TaskList extends Node { return js; } + // 生成更新任务列表的JSON对象的方法,用于与外部系统(可能是gtask服务端)交互,指定更新任务列表的相关信息 public JSONObject getUpdateAction(int actionId) { JSONObject js = new JSONObject(); try { - // action_type + // 设置操作类型为更新任务列表(假设GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE是一个常量表示更新操作类型) js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE); - // action_id + // 设置操作ID js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId); - // id + // 设置任务列表ID js.put(GTaskStringUtils.GTASK_JSON_ID, getGid()); - // entity_delta + // 创建任务列表实体的JSON对象 JSONObject entity = new JSONObject(); + // 设置任务列表名称 entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName()); + // 设置任务列表的删除标记 entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted()); + // 将任务列表实体添加到操作JSON对象中 js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity); } catch (JSONException e) { + // 如果在创建JSON对象过程中发生异常,记录错误日志,打印堆栈跟踪,并抛出ActionFailureException异常,表示生成更新任务列表的JSON对象失败 Log.e(TAG, e.toString()); e.printStackTrace(); throw new ActionFailureException("fail to generate tasklist-update jsonobject"); @@ -103,25 +116,27 @@ public class TaskList extends Node { return js; } + // 根据远程JSON数据设置任务列表内容的方法,从远程获取的JSON数据中解析并设置任务列表的各种属性(如ID、最后修改时间、名称) public void setContentByRemoteJSON(JSONObject js) { if (js != null) { try { - // id + // 如果JSON对象中包含任务列表ID,则设置任务列表ID if (js.has(GTaskStringUtils.GTASK_JSON_ID)) { setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID)); } - // last_modified + // 如果JSON对象中包含最后修改时间,则设置最后修改时间 if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) { setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)); } - // name + // 如果JSON对象中包含任务列表名称,则设置任务列表名称 if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) { setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME)); } } catch (JSONException e) { + // 如果在解析JSON数据过程中发生异常,记录错误日志,打印堆栈跟踪,并抛出ActionFailureException异常,表示从JSON对象获取任务列表内容失败 Log.e(TAG, e.toString()); e.printStackTrace(); throw new ActionFailureException("fail to get tasklist content from jsonobject"); @@ -129,6 +144,7 @@ public class TaskList extends Node { } } + // 根据本地JSON数据设置任务列表内容的方法,从本地存储的JSON数据中解析并设置任务列表的名称(根据特定的结构和条件,区分文件夹类型和系统类型) public void setContentByLocalJSON(JSONObject js) { if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) { Log.w(TAG, "setContentByLocalJSON: nothing is avaiable"); @@ -157,6 +173,7 @@ public class TaskList extends Node { } } + // 从任务列表内容生成本地JSON对象的方法,根据任务列表的当前状态构建用于本地存储或传输的JSON对象(包含任务列表名称、类型等信息 public JSONObject getLocalJSONFromContent() { try { JSONObject js = new JSONObject(); @@ -183,28 +200,29 @@ public class TaskList extends Node { } } + // 从任务列表内容生成本地JSON对象的方法,根据任务列表的当前状态构建用于本地存储或传输的JSON对象(包含任务列表名称、类型等信息 public int getSyncAction(Cursor c) { try { if (c.getInt(SqlNote.LOCAL_MODIFIED_COLUMN) == 0) { - // there is no local update + // 如果本地没有更新 if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // no update both side + // 双方都没有更新 return SYNC_ACTION_NONE; } else { - // apply remote to local + // 应用远程更新到本地 return SYNC_ACTION_UPDATE_LOCAL; } } else { - // validate gtask id + // 验证gtask ID是否匹配 if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) { Log.e(TAG, "gtask id doesn't match"); return SYNC_ACTION_ERROR; } if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) { - // local modification only + // 只有本地修改 return SYNC_ACTION_UPDATE_REMOTE; } else { - // for folder conflicts, just apply local modification + // 对于文件夹冲突,只应用本地修改(可能是一种特定的业务逻辑) return SYNC_ACTION_UPDATE_REMOTE; } } @@ -216,16 +234,18 @@ public class TaskList extends Node { return SYNC_ACTION_ERROR; } + // 获取任务列表中任务数量的方法 public int getChildTaskCount() { return mChildren.size(); } + // 向任务列表中添加任务的方法,将任务添加到任务列表末尾,并设置任务的前一个兄弟任务和父任务列表 public boolean addChildTask(Task task) { boolean ret = false; if (task != null && !mChildren.contains(task)) { ret = mChildren.add(task); if (ret) { - // need to set prior sibling and parent + // 需要设置前一个兄弟任务和父任务 task.setPriorSibling(mChildren.isEmpty() ? null : mChildren .get(mChildren.size() - 1)); task.setParent(this); @@ -234,6 +254,7 @@ public class TaskList extends Node { return ret; } + // 向任务列表中指定位置添加任务的方法,根据指定索引将任务插入到任务列表中,并更新任务列表中任务的前一个兄弟任务关系 public boolean addChildTask(Task task, int index) { if (index < 0 || index > mChildren.size()) { Log.e(TAG, "add child task: invalid index"); @@ -244,7 +265,7 @@ public class TaskList extends Node { if (task != null && pos == -1) { mChildren.add(index, task); - // update the task list + // 更新任务列表 Task preTask = null; Task afterTask = null; if (index != 0) @@ -260,6 +281,7 @@ public class TaskList extends Node { return true; } + // 从任务列表中移除任务的方法,从任务列表中移除指定任务,并重置任务的前一个兄弟任务和父任务关系,同时更新任务列表中任务的前一个兄弟任务关系 public boolean removeChildTask(Task task) { boolean ret = false; int index = mChildren.indexOf(task); @@ -267,11 +289,11 @@ public class TaskList extends Node { ret = mChildren.remove(task); if (ret) { - // reset prior sibling and parent + // 重置前一个兄弟任务和父任务 task.setPriorSibling(null); task.setParent(null); - // update the task list + // 更新任务列表 if (index != mChildren.size()) { mChildren.get(index).setPriorSibling( index == 0 ? null : mChildren.get(index - 1)); @@ -281,6 +303,7 @@ public class TaskList extends Node { return ret; } + // 在任务列表中移动任务到指定位置的方法,先移除任务再添加到指定位置,实现任务在任务列表中的移动 public boolean moveChildTask(Task task, int index) { if (index < 0 || index >= mChildren.size()) { @@ -299,6 +322,7 @@ public class TaskList extends Node { return (removeChildTask(task) && addChildTask(task, index)); } + // 根据任务ID查找任务列表中的任务的方法,遍历任务列表,查找并返回具有指定ID的任务,如果未找到则返回null public Task findChildTaskByGid(String gid) { for (int i = 0; i < mChildren.size(); i++) { Task t = mChildren.get(i); @@ -309,10 +333,12 @@ public class TaskList extends Node { return null; } + // 获取任务在任务列表中的索引的方法,返回任务在任务列表中的位置索引,如果任务不在列表中则返回 -1 public int getChildTaskIndex(Task task) { return mChildren.indexOf(task); } + // 根据索引获取任务列表中的任务的方法,根据指定索引返回任务列表中的任务,如果索引无效则记录错误日志并返回null public Task getChildTaskByIndex(int index) { if (index < 0 || index >= mChildren.size()) { Log.e(TAG, "getTaskByIndex: invalid index"); @@ -321,6 +347,7 @@ public class TaskList extends Node { return mChildren.get(index); } + // 根据任务ID获取任务列表中的任务的方法(与findChildTaskByGid方法功能类似,可能是为了提供不同的查找方式) public Task getChilTaskByGid(String gid) { for (Task task : mChildren) { if (task.getGid().equals(gid)) @@ -328,15 +355,17 @@ public class TaskList extends Node { } return null; } - + // 获取任务列表中所有任务的列表的方法 public ArrayList getChildTaskList() { return this.mChildren; } + // 设置任务列表索引的方法 public void setIndex(int index) { this.mIndex = index; } + // 获取任务列表索引的方法 public int getIndex() { return this.mIndex; } diff --git a/src/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java b/src/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java index 15504be..6c8ab49 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java +++ b/src/Notes-master/src/net/micode/notes/gtask/exception/ActionFailureException.java @@ -15,18 +15,22 @@ */ package net.micode.notes.gtask.exception; - +// 定义一个名为ActionFailureException的异常类,它继承自RuntimeException,表示运行时异常 public class ActionFailureException extends RuntimeException { + // serialVersionUID用于在序列化和反序列化过程中验证类的版本一致性 private static final long serialVersionUID = 4425249765923293627L; + // 无参构造函数,调用父类(RuntimeException)的无参构造函数 public ActionFailureException() { super(); } + // 带字符串参数的构造函数,将传入的字符串作为异常信息传递给父类构造函数 public ActionFailureException(String paramString) { super(paramString); } + // 带字符串和Throwable参数的构造函数,将传入的字符串作为异常信息,Throwable作为异常原因传递给父类构造函数 public ActionFailureException(String paramString, Throwable paramThrowable) { super(paramString, paramThrowable); } diff --git a/src/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java b/src/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java index b08cfb1..685b7e7 100644 --- a/src/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java +++ b/src/Notes-master/src/net/micode/notes/gtask/exception/NetworkFailureException.java @@ -16,17 +16,22 @@ package net.micode.notes.gtask.exception; +// 定义一个名为NetworkFailureException的异常类,它继承自Exception,表示这是一个需要被检查处理的异常 public class NetworkFailureException extends Exception { + // serialVersionUID用于在序列化和反序列化过程中验证类的版本一致性 private static final long serialVersionUID = 2107610287180234136L; + // 无参构造函数,调用父类(Exception)的无参构造函数 public NetworkFailureException() { super(); } + // 带字符串参数的构造函数,将传入的字符串作为异常信息传递给父类构造函数 public NetworkFailureException(String paramString) { super(paramString); } + // 带字符串和Throwable参数的构造函数,将传入的字符串作为异常信息,Throwable作为异常原因传递给父类构造函数 public NetworkFailureException(String paramString, Throwable paramThrowable) { super(paramString, paramThrowable); }