You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
xiaomi-Notes/Task.java

697 lines
33 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/*
* Copyright (c) 2010-2011, The MiCode Open Source Community (www.micode.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
//包声明:
// 该类属于 net.micode.notes.gtask.data 包,通常表示这是一个与 Google Tasks 或某个任务管理相关的数据模型类。
package net.micode.notes.gtask.data;
//导入 Cursor 类:
// Cursor 是 Android 中用于从数据库中查询数据的接口,通常用于访问 SQLite 数据库中的记录。
import android.database.Cursor;
//导入 TextUtils 类:
// TextUtils 是 Android 提供的工具类,包含了一些常用的字符串操作方法,如判断字符串是否为空或是否匹配某些模式等。
import android.text.TextUtils;
//导入 Log 类:
// Log 类用于 Android 中的日志输出,开发者可以使用它记录调试信息、错误日志等。
import android.util.Log;
//导入 Notes 类:
// 这个类可能是应用中用于表示便签或任务的类。Notes 类中的常量和方法通常用于访问或操作任务和便签相关的数据。
import net.micode.notes.data.Notes;
//导入 DataColumns, DataConstants, NoteColumns
// 这些导入语句表明,这些类包含 Notes 类中的常量和字段,它们可能用于表示与任务或便签相关的列名、常量定义等。
import net.micode.notes.data.Notes.DataColumns;
import net.micode.notes.data.Notes.DataConstants;
import net.micode.notes.data.Notes.NoteColumns;
//导入 ActionFailureException 类:
// 这个自定义异常类 ActionFailureException 可能用于处理在执行某些操作时发生的错误,表示某些操作失败。
import net.micode.notes.gtask.exception.ActionFailureException;
//导入 GTaskStringUtils 工具类:
// 这个类看起来是与 Google Tasks 相关的字符串工具类,可能包含处理任务相关字符串的实用方法。
import net.micode.notes.tool.GTaskStringUtils;
//导入 org.json 库的类:这些类用于处理 JSON 数据。
// 在任务管理应用中,任务通常是以 JSON 格式存储或传输的JSONArray, JSONException, 和 JSONObject 提供了处理 JSON 数据所需的工具。
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
//类Task 类继承自 Node 类,表示任务的基本模型,包含任务的状态、备注、父任务、优先级等信息。
//Task 类的构造函数:
//初始化了 mCompleted任务是否完成、mNotes任务备注、mPriorSibling前一个兄弟任务
// mParent父任务列表和 mMetaInfo任务的元数据信息等属性。
public class Task extends Node {
// 用于日志输出时标识当前类名
private static final String TAG = Task.class.getSimpleName();
// 任务是否完成
private boolean mCompleted;
// 任务的备注信息
private String mNotes;
// 任务的元数据信息,可能包含额外的任务信息
private JSONObject mMetaInfo;
// 当前任务的前一个兄弟任务
private Task mPriorSibling;
// 当前任务所属的任务列表(父任务列表)
private TaskList mParent;
// 构造函数:初始化 Task 对象的默认值
public Task() {
// 调用父类构造函数(假设父类 Node 也有构造函数)
super();
// 默认任务未完成
mCompleted = false;
// 默认没有备注
mNotes = null;
// 默认没有前一个兄弟任务
mPriorSibling = null;
// 默认没有父任务列表
mParent = null;
// 默认没有元数据
mMetaInfo = null;
}
/**
* 生成任务创建的 JSON 数据,表示一个任务的创建动作。
*
* @param actionId 任务创建动作的 ID
* @return 生成的包含任务创建信息的 JSONObject
*/
/*
方法getCreateAction(int actionId) 生成一个包含任务创建信息的 JSONObject用于表示一个任务创建的动作。
getCreateAction(int actionId) 方法:
功能:
该方法的主要任务是生成一个 JSONObject它表示创建任务的动作create action
这个 JSON 对象会包含任务的基本信息,比如名称、创建者 ID、任务类型、父任务 ID、任务列表 ID 等等。
步骤解析:
初始化 JSONObject创建一个新的 JSONObjectjs对象用于保存任务创建的所有信息。
设置基本属性:
action_type表示动作类型这里是创建任务。
action_id任务创建动作的唯一 ID通过方法参数 actionId 传入。
index任务在其父任务列表中的索引位置使用 mParent.getChildTaskIndex(this) 获取当前任务在父任务列表中的位置。
创建任务的基本信息:
创建一个名为 entity 的 JSON 对象,包含任务的名称、创建者 ID默认为 null、任务类型这里是 "task")等基本信息。
添加备注:
如果任务有备注mNotes 不为 null则将备注信息添加到 entity 中。
设置父任务 ID 和任务列表 ID
分别通过 mParent.getGid() 获取父任务列表的 ID并将其存储在 JSON 对象中。
设置前一个兄弟任务 ID
如果当前任务有前一个兄弟任务mPriorSibling != null则将其 ID 添加到 JSON 对象中。
错误处理:
在构建 JSON 的过程中,如果发生 JSONException 异常,记录错误信息并抛出自定义的 ActionFailureException。
JSONException 和 ActionFailureException
JSONException
这是 JSON 操作过程中可能抛出的异常,用于处理在构建 JSON 对象时出现的错误。
ActionFailureException
这是自定义的异常类,用于表示任务创建过程中操作失败的情况。在 JSON 构建失败时,抛出该异常。
日志记录:
使用 Log.e(TAG, e.toString()) 将错误信息打印到日志中,以便开发者调试时查看。
e.printStackTrace() 打印异常栈信息,帮助追踪错误的详细位置。
*/
public JSONObject getCreateAction(int actionId) {
// 创建一个新的 JSON 对象,用于保存任务的创建信息
JSONObject js = new JSONObject();
try {
// 设置 action_type表示这是一个任务创建的操作
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_CREATE);
// 设置 action_id任务创建动作的唯一 ID
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务在父任务列表中的索引位置
js.put(GTaskStringUtils.GTASK_JSON_INDEX, mParent.getChildTaskIndex(this));
// 创建一个 JSON 对象 entity用于表示任务的基本信息任务名称、创建者 ID、任务类型等
JSONObject entity = new JSONObject();
// 设置任务的名称
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// 设置任务创建者 ID这里默认为 "null"
entity.put(GTaskStringUtils.GTASK_JSON_CREATOR_ID, "null");
entity.put(GTaskStringUtils.GTASK_JSON_ENTITY_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_TASK); // 设置任务的类型为 "task"
// 如果任务有备注信息,添加备注到 entity 中
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
// 将任务的 entity 信息放入 JSON 中
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
// 设置任务的父任务 ID当前任务所在的任务列表的 ID
js.put(GTaskStringUtils.GTASK_JSON_PARENT_ID, mParent.getGid());
// 设置目标父级类型,这里固定为 "group" 类型
js.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT_TYPE,
GTaskStringUtils.GTASK_JSON_TYPE_GROUP);
// 设置任务列表的 ID父任务列表的 ID
js.put(GTaskStringUtils.GTASK_JSON_LIST_ID, mParent.getGid());
// 如果当前任务有前一个兄弟任务,则设置 prior_sibling_id
if (mPriorSibling != null) {
js.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, mPriorSibling.getGid());
}
} catch (JSONException e) {
// 如果生成 JSON 时发生错误,记录错误日志,并抛出自定义异常
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to generate task-create jsonobject");
}
// 返回生成的 JSON 对象
return js;
}
}
/*
方法功能:
getUpdateAction(int actionId) 生成一个 JSON 对象,表示任务的更新动作。这个 JSON 对象包含任务的 ID、名称、备注、删除标记等信息用于更新任务时进行传输或存储。
参数:
actionId表示当前任务更新动作的唯一 ID。
返回值:
返回一个 JSONObject包含任务更新的相关信息。
js.put()
这段代码使用 js.put() 方法将任务更新的相关数据填充到 JSON 对象中。
put() 方法是 JSONObject 类提供的一个 API用于向 JSON 对象中添加键值对。
更新操作的标识:
GTaskStringUtils.GTASK_JSON_ACTION_TYPE 设置为 GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE表示这是一个更新操作。
action_id
使用 actionId 参数设置更新操作的唯一 ID。
任务 ID
GTaskStringUtils.GTASK_JSON_ID 设置为 getGid(),表示当前任务的唯一 ID。getGid() 方法通常会返回任务的全局唯一标识符ID
任务实体更新:
创建一个名为 entity 的 JSON 对象,用于包含实际更新的任务信息:
任务名称:
GTaskStringUtils.GTASK_JSON_NAME 使用 getName() 方法获取任务的名称。
备注信息:
如果任务有备注getNotes() != null则将备注信息添加到 JSON 中。
删除标记:
GTaskStringUtils.GTASK_JSON_DELETED 使用 getDeleted() 方法来获取任务的删除标记(表示该任务是否已被标记为删除)。
错误处理:
如果在生成 JSON 对象的过程中发生 JSONException 异常,会记录错误信息并抛出自定义异常 ActionFailureException。
ActionFailureException 是一个自定义异常类,表示任务更新过程中的失败。异常信息为 "fail to generate task-update jsonobject",有助于开发者识别错误。
返回值:
方法最终返回一个包含任务更新信息的 JSONObject。这个 JSON 对象可以用于后续的任务更新操作,如提交到服务器或保存到数据库。
*/
public JSONObject getUpdateAction(int actionId) {
// 创建一个新的 JSON 对象,表示任务更新动作
JSONObject js = new JSONObject();
try {
// 设置 action_type 字段,表示这是一个更新操作
js.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_UPDATE);
// 设置 action_id 字段,表示当前更新操作的唯一标识符
js.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, actionId);
// 设置任务的 ID使用 `getGid()` 方法获取当前任务的唯一 ID
js.put(GTaskStringUtils.GTASK_JSON_ID, getGid());
// 创建一个 entity 对象,表示任务更新的实际内容(包括任务的名称、备注和删除标记)
JSONObject entity = new JSONObject();
// 设置任务的名称
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
// 如果任务有备注信息,则添加备注字段
if (getNotes() != null) {
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
// 设置任务的删除标记,使用 `getDeleted()` 方法获取任务是否已删除
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
// 将 entity 对象放入 JSON 中,作为任务更新的实际内容
js.put(GTaskStringUtils.GTASK_JSON_ENTITY_DELTA, entity);
} catch (JSONException e) {
// 捕获 JSON 构建过程中的异常
// 打印错误日志
Log.e(TAG, e.toString());
// 输出堆栈信息
e.printStackTrace();
// 如果发生异常,抛出自定义的更新失败异常
throw new ActionFailureException("fail to generate task-update jsonobject");
}
// 返回生成的任务更新 JSON 对象
return js;
}
/*
这段代码展示了一个 `setContentByRemoteJSON(JSONObject js)` 方法,它用于根据从远程服务器或外部系统接收到的 JSON 数据更新任务的属性
- **方法功能**`setContentByRemoteJSON(JSONObject js)` 根据传入的 JSON 对象,更新当前任务的各个属性。该方法会检查 JSON 中是否包含某些字段,并根据字段的存在情况,调用相应的 setter 方法更新任务的属性值。
- **参数**`js`,一个 `JSONObject`,包含任务更新的信息。
- **返回值**:无返回值。该方法直接更新任务对象的属性。
1. **检查 JSON 对象是否为空**
- 该方法首先检查传入的 `js` 对象是否为 `null`。如果是 `null`,说明没有数据需要处理,方法会直接退出。
2. **处理各个属性字段**
- 代码通过 `js.has()` 方法检查 JSON 对象中是否包含特定字段。如果字段存在,就从 JSON 中提取相应的值,并通过 setter 方法更新任务对象的属性。
- 对应的字段名称通过 `GTaskStringUtils` 类中的常量定义,如 `GTASK_JSON_ID`、`GTASK_JSON_LAST_MODIFIED`、`GTASK_JSON_NAME` 等。这些常量在其他地方应该有定义,用于确保字段名称的一致性,避免硬编码的字符串。
3. **具体字段的处理**
- **任务 ID**:使用 `getString()` 获取任务 ID并通过 `setGid()` 方法更新任务的全局 ID。
- **最后修改时间**:使用 `getLong()` 获取任务的最后修改时间,并通过 `setLastModified()` 方法更新。
- **任务名称**:使用 `getString()` 获取任务名称,并通过 `setName()` 方法更新。
- **备注信息**:使用 `getString()` 获取任务的备注,如果备注字段存在,就更新备注信息。
- **删除标记**:使用 `getBoolean()` 获取任务的删除标记(布尔值),并通过 `setDeleted()` 更新。
- **完成标记**:使用 `getBoolean()` 获取任务的完成标记(布尔值),并通过 `setCompleted()` 更新。
4. **异常处理**
- 如果在从 JSON 中提取数据的过程中发生 `JSONException` 异常,会打印错误信息并抛出自定义异常 `ActionFailureException`,该异常指示任务内容从 JSON 对象中获取失败。
- 异常消息中说明了错误是由于无法从 JSON 对象获取任务内容("fail to get task content from jsonobject")。
5. **setter 方法**
- `setGid()`, `setLastModified()`, `setName()`, `setNotes()`, `setDeleted()`, 和 `setCompleted()` 等方法是用于设置任务属性的自定义方法。
这些方法应该在任务对象的类中定义,用来更新任务对象的相应字段。
- 该方法通过从传入的 JSON 对象中提取任务相关的信息(如任务 ID、最后修改时间、名称、备注、删除标记、完成标记等并通过调用相应的 setter 方法来更新任务对象的属性。
- 在实现时,使用了 `js.has()` 来判断是否包含某个字段,避免了因字段缺失而导致的异常。
- 错误处理机制较为健全,当解析 JSON 过程中发生异常时,会记录日志并抛出自定义异常,以便调用者进行处理。
*/
public void setContentByRemoteJSON(JSONObject js) {
// 如果传入的 JSON 对象不为 null
if (js != null) {
try {
// 处理任务 ID获取并设置任务的全局 ID
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
// 处理任务的最后修改时间,获取并设置
if (js.has(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED)) {
setLastModified(js.getLong(GTaskStringUtils.GTASK_JSON_LAST_MODIFIED));
}
// 处理任务名称,获取并设置
if (js.has(GTaskStringUtils.GTASK_JSON_NAME)) {
setName(js.getString(GTaskStringUtils.GTASK_JSON_NAME));
}
// 处理任务备注,获取并设置
if (js.has(GTaskStringUtils.GTASK_JSON_NOTES)) {
setNotes(js.getString(GTaskStringUtils.GTASK_JSON_NOTES));
}
// 处理删除标记,获取并设置
if (js.has(GTaskStringUtils.GTASK_JSON_DELETED)) {
setDeleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_DELETED));
}
// 处理完成标记,获取并设置
if (js.has(GTaskStringUtils.GTASK_JSON_COMPLETED)) {
setCompleted(js.getBoolean(GTaskStringUtils.GTASK_JSON_COMPLETED));
}
} catch (JSONException e) {
// 如果解析 JSON 过程中发生异常,打印错误信息并抛出自定义异常
Log.e(TAG, e.toString());
e.printStackTrace();
throw new ActionFailureException("fail to get task content from jsonobject");
}
}
}
/*
功能:
从本地的 JSON 数据中提取相关内容,更新任务的名称。如果 JSON 格式正确且符合预期,它会提取相关字段并更新任务的 name 属性。否则,方法会打印警告信息或错误信息。
参数:
js一个包含任务信息的 JSONObject格式应包括 META_HEAD_NOTE 和 META_HEAD_DATA 这两个字段。
返回值:
无返回值,直接修改任务对象的属性。
*/
public void setContentByLocalJSON(JSONObject js) {
// 检查传入的 JSON 是否为 null且是否包含所需的两个字段
/*
这段代码首先检查传入的 js 对象是否为 null以及它是否包含两个特定字段META_HEAD_NOTE 和 META_HEAD_DATA。
这两个字段是该方法解析任务内容所依赖的。如果这两个字段不存在,或者 js 为 null则会打印警告日志并返回避免进一步的处理。
*/
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
// 如果条件不满足,打印警告信息并返回
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
try {
/*如果 JSON 对象有效并且包含所需字段,
接下来会从 JSON 对象中提取出 META_HEAD_NOTE 部分(作为 note 对象)和 META_HEAD_DATA 部分(作为 dataArray 数组)
*/
// 从 JSON 中提取出 META_HEAD_NOTE 对应的 JSONObject
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
// 从 JSON 中提取出 META_HEAD_DATA 对应的 JSONArray
JSONArray dataArray = js.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 检查 note 对象中的 TYPE 是否为 NOTE 类型
//通过 note.getInt(NoteColumns.TYPE) 获取 note 对象中的 TYPE 字段,并与 Notes.TYPE_NOTE 常量进行比较。
// 如果 TYPE 不等于 Notes.TYPE_NOTE假设 Notes.TYPE_NOTE 是预定义的常量,表示有效的 note 类型),
// 则认为该数据无效,打印错误日志并退出方法。
if (note.getInt(NoteColumns.TYPE) != Notes.TYPE_NOTE) {
// 如果 TYPE 不等于 NOTE 类型,打印错误信息并返回
Log.e(TAG, "invalid type");
return;
}
// 遍历 dataArray 数组中的每个 JSONObject
/*方法通过 dataArray.length() 获取数组的长度,使用 for 循环遍历数组中的每一个 data 对象。
在每次迭代中,通过 data.getString(DataColumns.MIME_TYPE) 获取 MIME_TYPE 字段,
并与 DataConstants.NOTE 常量进行比较。如果 MIME_TYPE 的值是 NOTE则获取该 data 对象的 CONTENT 字段值,
并调用 setName() 方法更新任务的名称。
一旦找到符合条件的 data 对象,便立即跳出循环(使用 break 语句)
*/
for (int i = 0; i < dataArray.length(); i++) {
// 获取当前遍历的 data 对象
JSONObject data = dataArray.getJSONObject(i);
// 判断 data 中的 MIME_TYPE 是否为 NOTE 类型
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
// 如果 MIME_TYPE 为 NOTE 类型,从 data 中获取 CONTENT 字段的值,并设置为任务的名称
setName(data.getString(DataColumns.CONTENT));
// 找到第一个符合条件的记录后跳出循环
break;
}
}
}
//如果在解析 JSON 数据时发生异常(例如字段缺失或类型不匹配),会捕获 JSONException 并打印错误信息,确保应用不会崩溃。
catch (JSONException e) {
// 如果在解析过程中发生异常,打印错误信息
Log.e(TAG, e.toString());
// 打印堆栈跟踪信息
e.printStackTrace();
}
}
/*
该方法 getLocalJSONFromContent() 的主要功能是根据当前任务的状态生成或更新本地的 JSON 对象JSONObject
该对象表示任务的元数据。它会根据任务是否已经同步(即是否有 mMetaInfo来决定是创建一个新的 JSON 对象,还是更新已有的同步任务的数据。
*/
public JSONObject getLocalJSONFromContent() {
// 获取当前任务的名称
String name = getName();
try {
// 如果 mMetaInfo 为 null表示任务还未同步或者是一个新任务
if (mMetaInfo == null) {
// new task created from web
// 如果任务的名称为空,输出警告并返回 null
if (name == null) {
Log.w(TAG, "the note seems to be an empty one");
return null;
}
// 创建一个新的 JSON 对象来表示任务的元数据
JSONObject js = new JSONObject();
JSONObject note = new JSONObject();
JSONArray dataArray = new JSONArray();
JSONObject data = new JSONObject();
// 将任务的名称添加到 data 对象中
data.put(DataColumns.CONTENT, name);
// 将 data 对象添加到 dataArray 中
dataArray.put(data);
// 将 dataArray 添加到 js 对象中的 META_HEAD_DATA 字段
js.put(GTaskStringUtils.META_HEAD_DATA, dataArray);
// 设置 note 对象的 TYPE 字段为 NOTE 类型
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
// 将 note 对象添加到 js 对象中的 META_HEAD_NOTE 字段
js.put(GTaskStringUtils.META_HEAD_NOTE, note);
return js; // 返回生成的 JSON 对象
} else {
// 如果 mMetaInfo 已经存在,表示这是一个已经同步的任务
// 从 mMetaInfo 中获取 META_HEAD_NOTE 和 META_HEAD_DATA
JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
// 遍历 dataArray 中的每个 data 对象,更新 MIME_TYPE 为 NOTE 的对象中的 CONTENT 字段
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
if (TextUtils.equals(data.getString(DataColumns.MIME_TYPE), DataConstants.NOTE)) {
// 更新 data 对象中的 CONTENT 字段为当前任务的名称
data.put(DataColumns.CONTENT, getName());
break; // 找到并更新后跳出循环
}
}
// 确保 note 对象中的 TYPE 字段仍然为 NOTE 类型
note.put(NoteColumns.TYPE, Notes.TYPE_NOTE);
// 返回已经更新的 mMetaInfo 对象
return mMetaInfo;
}
}
// 捕获并处理 JSON 解析过程中的异常
catch (JSONException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
// 如果发生异常,返回 null
return null;
}
}
/*
setMetaInfo(MetaData metaData)
该方法接受一个 MetaData 对象作为参数,目的是将 metaData 中的 notes 信息转换为 JSONObject并赋值给 mMetaInfo。
如果传入的 metaData 和 metaData.getNotes() 不为 null会尝试将 getNotes() 返回的字符串解析为 JSONObject并赋值给 mMetaInfo。
如果解析过程中发生错误(如 JSON 格式不合法),会捕获 JSONException输出警告信息并将 mMetaInfo 置为 null。
*/
public void setMetaInfo(MetaData metaData) {
if (metaData != null && metaData.getNotes() != null) {
try {
// 将 notes 字符串转换为 JSONObject
mMetaInfo = new JSONObject(metaData.getNotes());
}
catch (JSONException e) { // 如果 JSON 转换失败
// 输出警告日志
Log.w(TAG, e.toString());
// 设置 mMetaInfo 为 null
mMetaInfo = null;
}
}
}
/*
getSyncAction(Cursor c)
该方法根据当前任务的同步状态,决定接下来的同步操作(如更新远程或本地数据等)。
逻辑说明:
该方法首先检查 mMetaInfo 是否包含有效的 note 元数据。
然后,它根据当前数据库记录(通过 Cursor 提供的数据)与 mMetaInfo 中的 note 数据进行比较,确定要执行的同步操作:
SYNC_ACTION_UPDATE_REMOTE从远程更新数据。
SYNC_ACTION_UPDATE_LOCAL将远程数据应用到本地。
SYNC_ACTION_NONE本地和远程都没有更新不需要同步。
SYNC_ACTION_UPDATE_CONFLICT本地和远程都进行了修改发生冲突。
SYNC_ACTION_ERROR出现错误或无法同步。
*/
public int getSyncAction(Cursor c) {
try {
JSONObject noteInfo = null;
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
// 获取 note 元数据
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
}
// 如果没有获取到 note 信息
if (noteInfo == null) {
Log.w(TAG, "it seems that note meta has been deleted");
// 需要从远程更新
return SYNC_ACTION_UPDATE_REMOTE;
}
// 如果 note 缺少 ID 字段
if (!noteInfo.has(NoteColumns.ID)) {
Log.w(TAG, "remote note id seems to be deleted");
// 需要从本地更新
return SYNC_ACTION_UPDATE_LOCAL;
}
// 校验 note 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) {
// 本地和远程都没有变化
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// 无需操作
return SYNC_ACTION_NONE;
} else { // 远程有更新
// 从远程更新
return SYNC_ACTION_UPDATE_LOCAL;
}
} else { // 本地已修改
// 校验 gtask ID
if (!c.getString(SqlNote.GTASK_ID_COLUMN).equals(getGid())) {
Log.e(TAG, "gtask id doesn't match");
// gtask ID 不匹配,返回错误
return SYNC_ACTION_ERROR;
}
// 本地修改且没有远程修改
if (c.getLong(SqlNote.SYNC_ID_COLUMN) == getLastModified()) {
// 将本地修改同步到远程
return SYNC_ACTION_UPDATE_REMOTE;
} else {
// 本地和远程都有修改,发生冲突
return SYNC_ACTION_UPDATE_CONFLICT;
}
}
} catch (Exception e) {
// 异常处理
Log.e(TAG, e.toString());
e.printStackTrace();
}
// 出现异常或无法处理时返回错误
return SYNC_ACTION_ERROR;
}
/*
setCompleted(boolean completed)
作用:设置任务的完成状态。
参数completed 是一个布尔值,表示任务是否已完成。
*/
public void setCompleted(boolean completed) {
//将传入的 completed 参数赋值给任务对象的 mCompleted 属性,用于标识任务是否完成
this.mCompleted = completed;
}
/*
setNotes(String notes)
作用:设置任务的备注信息。
参数notes 是一个字符串,表示任务的备注或附加说明。
*/
public void setNotes(String notes) {
//将传入的 notes 参数赋值给任务对象的 mNotes 属性,用于存储任务的备注内容。
this.mNotes = notes;
}
/*
setPriorSibling(Task priorSibling)
作用:设置任务的前一个兄弟任务。
参数priorSibling 是一个 Task 对象,表示当前任务的前一个兄弟任务。
*/
public void setPriorSibling(Task priorSibling) {
//将传入的 priorSibling 参数赋值给任务对象的 mPriorSibling 属性,表示当前任务在任务列表中的前一个任务。
this.mPriorSibling = priorSibling;
}
/*
setParent(TaskList parent)
作用:设置任务的父任务列表。
参数parent 是一个 TaskList 对象,表示任务所属的任务列表。
*/
public void setParent(TaskList parent) {
//将传入的 parent 参数赋值给任务对象的 mParent 属性,表示当前任务所属的父任务列表。
this.mParent = parent;
}
/*
getCompleted()
作用:获取任务的完成状态。
返回值:返回一个布尔值,表示任务是否已完成。
*/
public boolean getCompleted() {
//返回 mCompleted 属性的值,表示任务是否已完成。
return this.mCompleted;
}
/*
getNotes()
作用:获取任务的备注信息。
返回值:返回任务的备注字符串。
*/
public String getNotes() {
//返回 mNotes 属性的值,表示任务的备注或附加说明。
return this.mNotes;
}
/*
getPriorSibling()
作用:获取任务的前一个兄弟任务。
返回值:返回一个 Task 对象,表示当前任务的前一个兄弟任务。
*/
public Task getPriorSibling() {
//返回 mPriorSibling 属性的值,表示当前任务在任务列表中的前一个任务。
return this.mPriorSibling;
}
/*
getParent()
作用:获取任务所属的父任务列表。
返回值:返回一个 TaskList 对象,表示任务所属的父任务列表。
*/
public TaskList getParent() {
// 返回 mParent 属性的值,表示当前任务所属的父任务列表。
return this.mParent;
}
}