From 0a0c03590561c1d7db7c8b4ede2c23594af213ef Mon Sep 17 00:00:00 2001 From: djq <1953187027@qq.com> Date: Sun, 24 Dec 2023 16:55:31 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E6=B3=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...泛读、标注和维护报告文档.docx | Bin 295107 -> 296425 bytes .../net/micode/notes/data/NotesProvider.java | 78 ++++++++++++++- .../net/micode/notes/gtask/data/MetaData.java | 38 +++++++- .../src/net/micode/notes/gtask/data/Node.java | 59 +++++++++-- .../net/micode/notes/gtask/data/SqlData.java | 92 +++++++++++++----- 5 files changed, 227 insertions(+), 40 deletions(-) diff --git a/doc/实践模板-开源软件泛读、标注和维护报告文档.docx b/doc/实践模板-开源软件泛读、标注和维护报告文档.docx index 598cbe12527c7b9f3308441e3c15900fb2ce83b3..02eb71364caa92912953d609488ac5b6c5f531ea 100644 GIT binary patch delta 17132 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 delta 15827 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 Ro~d1-Ff^a=d|*CW{|_reWM}{Y diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java b/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java index edb0a60..d7b3880 100644 --- a/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java +++ b/src/xiaomi/Notes-master/src/net/micode/notes/data/NotesProvider.java @@ -34,7 +34,15 @@ import net.micode.notes.data.Notes.DataColumns; import net.micode.notes.data.Notes.NoteColumns; import net.micode.notes.data.NotesDatabaseHelper.TABLE; - +/** + * @Package: net.micode.notes.data + * @ClassName: NotesProvider + * @Description: + * 这个类是对ContentProvider类的扩展,功能是提供小米便签应用程序的数据, + * 在类当中实现了数据库的增添删减修改查找操作,并且可以处理与搜索有关的查询。 + * @Author: Dong Jiaqi + * @CreateDate: 12/23/2023 23:27 PM + */ public class NotesProvider extends ContentProvider { private static final UriMatcher mMatcher; @@ -50,6 +58,10 @@ public class NotesProvider extends ContentProvider { private static final int URI_SEARCH = 5; private static final int URI_SEARCH_SUGGEST = 6; + /** + * 定义了一个静态代码块,初始化UriMatcher对象并且添加匹配规则 + * 调用了addURI()方法,向mMatcher这一个UriMatcher对象中添加了一系列匹配规则 + */ static { mMatcher = new UriMatcher(UriMatcher.NO_MATCH); mMatcher.addURI(Notes.AUTHORITY, "note", URI_NOTE); @@ -79,18 +91,36 @@ public class NotesProvider extends ContentProvider { + " AND " + NoteColumns.PARENT_ID + "<>" + Notes.ID_TRASH_FOLER + " AND " + NoteColumns.TYPE + "=" + Notes.TYPE_NOTE; + /** + * onCreate()方法的功能是在应用程序启动时进行初始化数据库帮助类 + * @return 返回true表示创建成功 + */ @Override public boolean onCreate() { mHelper = NotesDatabaseHelper.getInstance(getContext()); return true; } + /** + * query()方法用于执行查询操作,根据传入的URI参数,选择执行不同的查询语句返回 + * @param uri 要查询数据的URI,用来确定要操作的表和行 + * @param projection 表示查询返回的列的数组,可以指定查询结果中包含的列 + * @param selection 表示用于筛选的条件 + * @param selectionArgs 表示selection中的占位符的值 + * @param sortOrder 表示查询结果的排序顺序 + * @return 返回查询结果的游标(Cursor)对象(c) + */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor c = null; SQLiteDatabase db = mHelper.getReadableDatabase(); String id = null; + /** + * 这是一个switch语句块,用来针对不同的URI进行不同的操作。 + * 对于3种类型的URI,进行了不同的操作,如果URI不匹配这任何一种情况,就视为ILLegalArgumentException异常,表示URI不被支持或不合法 + * 这个语句块的目的是为了处理不同类型的URI,并且根据URI类型执行相应的数据库查询操作,属于典型的Android ContentProvider的逻辑处理代码 + */ switch (mMatcher.match(uri)) { case URI_NOTE: c = db.query(TABLE.NOTE, projection, selection, selectionArgs, null, null, @@ -130,6 +160,11 @@ public class NotesProvider extends ContentProvider { return null; } + /** + * 这个语句块是在处理 URI_SEARCH 和 URI_SEARCH_SUGGEST 的情况下执行的,主要功能是执行数据库的原始查询(rawQuery)操作,用于搜索符合指定条件的数据,并将结果存储在 Cursor 对象中。 + * 如果在执行数据库查询时发生 IllegalStateException 异常,那么异常信息会被捕获,并通过 Log.e() 方法记录下来,方便在日志中进行查看和分析。 + * 目的是为了在执行数据库查询时,确保搜索关键词被正确地格式化并传入查询语句中,同时也确保在出现数据库查询异常时能够进行相应的异常处理和记录。 + */ try { searchString = String.format("%%%s%%", searchString); c = db.rawQuery(NOTES_SNIPPET_SEARCH_QUERY, @@ -147,6 +182,12 @@ public class NotesProvider extends ContentProvider { return c; } + /** + * 用于执行插入操作,根据传入的URI参数,选择在不同的表中进行插入 + * @param uri 传入数据的URI,用来确定要操作的表和行 + * @param values 表示要插入的数据集合 + * @return 返回插入数据的URI,即ContentUris.withAppendedId(uri, insertedId) + */ @Override public Uri insert(Uri uri, ContentValues values) { SQLiteDatabase db = mHelper.getWritableDatabase(); @@ -181,6 +222,13 @@ public class NotesProvider extends ContentProvider { return ContentUris.withAppendedId(uri, insertedId); } + /** + * 执行删除操作,根据传入URI参数,选择在不同的表中执行删除操作 + * @param uri 传入数据的URI,用来确定要操作的表和行 + * @param selection 表示删除的条件 + * @param selectionArgs 表示selection中的占位符的值 + * @return 返回收到影响的内容行数 + */ @Override public int delete(Uri uri, String selection, String[] selectionArgs) { int count = 0; @@ -227,12 +275,25 @@ public class NotesProvider extends ContentProvider { return count; } + /** + * 执行更新操作,根据传入URI参数,在不同的表中进行更新 + * @param uri 传入数据的URI,用来确定要操作的表和行 + * @param values 表示要更新的数据集合 + * @param selection 表示用于筛选的条件 + * @param selectionArgs 表示selection中的占位符的值 + * @return 返回收到影响的行数 + */ @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { int count = 0; String id = null; SQLiteDatabase db = mHelper.getWritableDatabase(); boolean updateData = false; + /** + * 这个语句块根据传入的 URI(Uniform Resource Identifier)进行匹配,并执行相应的操作。 + * 目的是根据传入的 URI 执行相应的数据库更新操作。根据不同的 URI,可以实现对不同表和记录的更新操作。 + * 通过 switch-case 结构,可以清晰地处理不同的情况,并执行相应的操作,同时也提供了一个默认的处理方式来处理未知的 URI。 + */ switch (mMatcher.match(uri)) { case URI_NOTE: increaseNoteVersion(-1, selection, selectionArgs); @@ -267,10 +328,21 @@ public class NotesProvider extends ContentProvider { return count; } + /** + * 用于解析查询条件,将其转换为SQL语句中的WHERE子句 + * @param selection 表示用来解析的条件 + * @return 返回转换后的字符串 + */ private String parseSelection(String selection) { return (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""); } + /** + * 用于增加便签的版本号 + * @param id 要增加版本号的便签的ID + * @param selection 查询选择条件,用来筛选要增加版本号的便签 + * @param selectionArgs 表示占位符参数 + */ private void increaseNoteVersion(long id, String selection, String[] selectionArgs) { StringBuilder sql = new StringBuilder(120); sql.append("UPDATE "); @@ -296,6 +368,10 @@ public class NotesProvider extends ContentProvider { mHelper.getWritableDatabase().execSQL(sql.toString()); } + /** + * 该方法根据需要自行补充实现,给开源后其他软件工程师留下了增添空间 + * @param uri 数据的URI + */ @Override public String getType(Uri uri) { // TODO Auto-generated method stub diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java index 3a2050b..1699caa 100644 --- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java +++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/MetaData.java @@ -24,13 +24,33 @@ import net.micode.notes.tool.GTaskStringUtils; import org.json.JSONException; import org.json.JSONObject; - +/** + * @Package: net.micode.notes.gtask.data + * @ClassName: MetaData + * @Description: + * MetaData类继承自 Task 类。它用于处理任务的元数据信息,并封装了一些操作元数据的方法。 + * 这个类用于管理任务的元数据信息,包括相关的 GID,在设置和获取元数据的同时,还提供了判断任务是否值得保存的方法,以及根据远程 JSON 数据设置任务内容的方法。 + * 同时,限制了部分方法的访问,以确保其按照预期的方式被使用。 + * @Author: Dong Jiaqi + * @CreateDate: 12/24/2023 9:53 AM + */ public class MetaData extends Task { private final static String TAG = MetaData.class.getSimpleName(); private String mRelatedGid = null; + /** + * 作用是将给定的 GID 和其他元数据信息添加到任务的注释信息中,并设置任务的名称为固定的值。 + * @param gid 表示任务的全局唯一标识符(Global Task ID),是一个字符串类型的参数。 + * @param metaInfo 表示元数据信息,是一个 JSONObject 对象,包含任务的其他相关信息。 + */ public void setMeta(String gid, JSONObject metaInfo) { + /** + * 这个语句块作用是向 metaInfo 这个 JSONObject 对象中添加一个键值对,其中键是 GTaskStringUtils.META_HEAD_GTASK_ID,值是变量 gid。 + * 使用了 try-catch 块来捕获可能抛出的 JSONException 异常。 + * 为什么要这么写呢: + * 因为在 Java 中,JSONObject 的 put 方法声明了可能抛出 JSONException 异常。这意味着在调用 put 方法时,需要进行异常处理,否则会导致编译错误。因此,为了保证程序的健壮性,开发者通常会在调用可能会引发异常的方法时使用 try-catch 块进行异常处理,以防止程序异常终止。 + */ try { metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid); } catch (JSONException e) { @@ -40,19 +60,29 @@ public class MetaData extends Task { setName(GTaskStringUtils.META_NOTE_NAME); } + //作用是获取任务的相关 GID,并返回其字符串形式。 public String getRelatedGid() { - return mRelatedGid; + return mRelatedGid;//返回值是一个字符串类型的变量 mRelatedGid,表示相关 GID(Global Task ID)。mRelatedGid 是一个成员变量,它保存了在任务的元数据信息中提取出来的相关 GID。 } + //作用是判断任务是否值得保存。它通过检查任务的注释信息是否为null来确定任务是否值得保存。 @Override public boolean isWorthSaving() { - return getNotes() != null; + return getNotes() != null;//如果注释信息不为null,则返回true,表示任务值得保存;反之,如果注释信息为null,则返回false,表示任务不值得保存。 } + /** + * 功能是从远程 JSON 对象中获取任务的内容,包括基本的任务属性和元数据信息,并将其存储到当前的 Task 对象中。 + * @param js JSONObject 对象,表示从远程服务器获取的任务信息。 + */ @Override public void setContentByRemoteJSON(JSONObject js) { super.setContentByRemoteJSON(js); if (getNotes() != null) { + /** + * 这个语句块作用是从任务的注释信息中提取相关 GID,并将其保存到变量 mRelatedGid 中。 + * 使用try-catch块是为了处理可能抛出的异常,确保程序稳定性 + */ try { JSONObject metaInfo = new JSONObject(getNotes().trim()); mRelatedGid = metaInfo.getString(GTaskStringUtils.META_HEAD_GTASK_ID); @@ -66,7 +96,7 @@ public class MetaData extends Task { @Override public void setContentByLocalJSON(JSONObject js) { // this function should not be called - throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called"); + throw new IllegalAccessError("MetaData:setContentByLocalJSON should not be called");//抛出一个IllegalAccessError异常,并且提供异常的详细描述信息 } @Override diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java index 63950e0..c2a5253 100644 --- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java +++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/Node.java @@ -20,24 +20,33 @@ import android.database.Cursor; import org.json.JSONObject; +/** + * @Package: net.micode.notes.gtask.data + * @ClassName: Node + * @Description: + * Node类是一个抽象类,定义了一些常量字段以及一些方法,还定义了节点对象的基本属性和操作, + * * 同时提供了抽象方法来处理节点内容的设置和同步操作的创建按,以及普通方法来设置和获取节点的属性。 + * @Author: Dong Jiaqi + * @CreateDate: 12/24/2023 10:23 AM + */ public abstract class Node { - public static final int SYNC_ACTION_NONE = 0; + public static final int SYNC_ACTION_NONE = 0;//表示没有同步操作。 - public static final int SYNC_ACTION_ADD_REMOTE = 1; + public static final int SYNC_ACTION_ADD_REMOTE = 1;//表示远程添加操作。 - public static final int SYNC_ACTION_ADD_LOCAL = 2; + public static final int SYNC_ACTION_ADD_LOCAL = 2;//表示本地添加操作。 - public static final int SYNC_ACTION_DEL_REMOTE = 3; + public static final int SYNC_ACTION_DEL_REMOTE = 3;//表示远程删除操作。 - public static final int SYNC_ACTION_DEL_LOCAL = 4; + public static final int SYNC_ACTION_DEL_LOCAL = 4;//表示本地删除操作。 - public static final int SYNC_ACTION_UPDATE_REMOTE = 5; + public static final int SYNC_ACTION_UPDATE_REMOTE = 5;//表示远程更新操作。 - public static final int SYNC_ACTION_UPDATE_LOCAL = 6; + public static final int SYNC_ACTION_UPDATE_LOCAL = 6;//表示本地更新操作。 - public static final int SYNC_ACTION_UPDATE_CONFLICT = 7; + public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;//表示更新冲突操作。 - public static final int SYNC_ACTION_ERROR = 8; + public static final int SYNC_ACTION_ERROR = 8;//表示同步错误操作。 private String mGid; @@ -66,34 +75,66 @@ public abstract class Node { public abstract int getSyncAction(Cursor c); + /** + * 设置节点对象的全局唯一标识符(gid)。 + * @param gid 表示要设置的全局唯一标识符,它是一个字符串类型的参数。可以是任意有效的字符串,用于对节点进行唯一标识和区分。 + */ public void setGid(String gid) { this.mGid = gid; } + /** + * 设置节点对象的名称。它通过将传入的字符串参数 name 赋值给节点对象的成员变量 mName 来实现。 + * @param name 表示要设置的节点名称,它是一个字符串类型的参数。可以是任意有效的字符串,用于标识节点的名称或描述。 + */ public void setName(String name) { this.mName = name; } + /** + * 设置节点对象的最后修改时间。它通过将传入的长整型参数 lastModified 赋值给节点对象的成员变量 mLastModified 来实现。 + * @param lastModified 表示要设置的节点的最后修改时间,它是一个长整型参数,用来记录节点对象的最后修改时间 + */ public void setLastModified(long lastModified) { this.mLastModified = lastModified; } + /** + * 设置节点对象的删除状态。它通过将传入的布尔类型参数 deleted 赋值给节点对象的成员变量 mDeleted 来实现。 + * @param deleted 表示要设置的节点的删除状态,它是一个布尔类型的参数。当该参数为 true 时,表示节点被标记为已删除;当该参数为 false 时,表示节点未被删除。 + */ public void setDeleted(boolean deleted) { this.mDeleted = deleted; } + /** + * 获取节点对象的全局唯一标识符(gid)。它通过返回节点对象的成员变量 mGid 的值来实现。 + * @return this.mGid表示节点的全局唯一标识符。这是一个字符串类型的返回值,用于表示节点对象的唯一标识符。 + */ public String getGid() { return this.mGid; } + /** + * 获取节点对象的名称。它通过返回节点对象的成员变量 mName 的值来实现。 + * @return this.mName表示节点的名称。这是一个字符串类型的返回值,用于表示节点对象的名称或描述。 + */ public String getName() { return this.mName; } + /** + * 获取节点对象的最后修改时间。它通过返回节点对象的成员变量 mLastModified 的值来实现。 + * @return this.mLastModified表示节点的最后修改时间。这是一个长整型的返回值 + */ public long getLastModified() { return this.mLastModified; } + /** + * 获取节点对象的删除状态。它通过返回节点对象的成员变量 mDeleted 的布尔值来实现。 + * @return 表示节点的删除状态。当返回值为 true 时,表示节点已被标记为已删除;当返回值为 false 时,表示节点未被删除。 + */ public boolean getDeleted() { return this.mDeleted; } diff --git a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java index d3ec3be..60f3022 100644 --- a/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java +++ b/src/xiaomi/Notes-master/src/net/micode/notes/gtask/data/SqlData.java @@ -34,26 +34,33 @@ import net.micode.notes.gtask.exception.ActionFailureException; import org.json.JSONException; import org.json.JSONObject; - +/** + * @Package: net.micode.notes.gtask.data + * @ClassName: SqlData + * @Description: + * 封装了对数据库中数据的读取、更新和提交操作,可以用于管理和操作数据库中的数据。 + * @Author: Dong Jiaqi + * @CreateDate: 12/24/2023 10:58 AM + */ public class SqlData { private static final String TAG = SqlData.class.getSimpleName(); - private static final int INVALID_ID = -99999; + private static final int INVALID_ID = -99999;//定义了一个名为 INVALID_ID 的私有静态整型常量,并赋值为 -99999,被用来表示无效的 ID 值。 public static final String[] PROJECTION_DATA = new String[] { DataColumns.ID, DataColumns.MIME_TYPE, DataColumns.CONTENT, DataColumns.DATA1, DataColumns.DATA3 - }; + };//定义了一个名为 PROJECTION_DATA 的字符串数组,其中包含了一组列名 - public static final int DATA_ID_COLUMN = 0; + public static final int DATA_ID_COLUMN = 0;//表示数据的 ID 在数据列中的索引位置,即第一列。 - public static final int DATA_MIME_TYPE_COLUMN = 1; + public static final int DATA_MIME_TYPE_COLUMN = 1;//表示数据的 MIME 类型在数据列中的索引位置,即第二列。 - public static final int DATA_CONTENT_COLUMN = 2; + public static final int DATA_CONTENT_COLUMN = 2;//表示数据的内容在数据列中的索引位置,即第三列。 - public static final int DATA_CONTENT_DATA_1_COLUMN = 3; + public static final int DATA_CONTENT_DATA_1_COLUMN = 3;//表示数据的内容数据1在数据列中的索引位置,即第四列。 - public static final int DATA_CONTENT_DATA_3_COLUMN = 4; + public static final int DATA_CONTENT_DATA_3_COLUMN = 4;//表示数据的内容数据3在数据列中的索引位置,即第五列。 private ContentResolver mContentResolver; @@ -71,36 +78,54 @@ public class SqlData { private ContentValues mDiffDataValues; + /** + * 构造函数,接收一个Context对象作为参数,并初始化成员变量。 + * @param context 用于获取应用程序的上下文信息,以便后续操作数据库。 + */ public SqlData(Context context) { - mContentResolver = context.getContentResolver(); + mContentResolver = context.getContentResolver();//这是构造方法的定义,表明这是一个公共的构造方法,并且接受一个 Context 类型的参数。 mIsCreate = true; mDataId = INVALID_ID; mDataMimeType = DataConstants.NOTE; - mDataContent = ""; + mDataContent = "";//成员变量初始化 mDataContentData1 = 0; mDataContentData3 = ""; - mDiffDataValues = new ContentValues(); + mDiffDataValues = new ContentValues();//创建新的ContentValues对象 } + /** + * 构造函数,接收一个Context对象和一个Cursor对象作为参数,并根据Cursor对象加载成员变量的值。 + * @param context 用于获取应用程序的上下文信息,以便后续操作数据库; + * @param c Cursor 对象用于获取数据库中的数据。 + */ public SqlData(Context context, Cursor c) { mContentResolver = context.getContentResolver(); mIsCreate = false; - loadFromCursor(c); + loadFromCursor(c);//调用 loadFromCursor() 方法,将传入的 Cursor 对象作为参数,以从 Cursor 对象中加载数据库中的数据到 SqlData 对象的成员变量中。 mDiffDataValues = new ContentValues(); } + /** + * 从传入的 Cursor 对象中加载数据,并将数据赋值给 SqlData 对象的各个成员变量。 + * @param c Cursor 对象用于获取数据库中的数据 + */ private void loadFromCursor(Cursor c) { - mDataId = c.getLong(DATA_ID_COLUMN); - mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN); + mDataId = c.getLong(DATA_ID_COLUMN);//从 Cursor 对象中获取指定列索引为 DATA_ID_COLUMN 的长整型数据,并赋值给 mDataId 成员变量。 + mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);//从 Cursor 对象中获取指定列索引为 DATA_MIME_TYPE_COLUMN 的字符串数据,并赋值给 mDataMimeType 成员变量。 mDataContent = c.getString(DATA_CONTENT_COLUMN); mDataContentData1 = c.getLong(DATA_CONTENT_DATA_1_COLUMN); mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN); } + /** + * 根据传入的JSON对象设置成员变量的值。根据JSON对象中的字段值判断是否需要更新成员变量,并将需要更新的值存储在mDiffDataValues对象中。 + * @param js JSONObject对象用于获取数据 + * @throws JSONException 抛出的异常 + */ public void setContent(JSONObject js) throws JSONException { - long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID; - if (mIsCreate || mDataId != dataId) { - mDiffDataValues.put(DataColumns.ID, dataId); + long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;//检查 JSON 对象 js 中是否包含名为 DataColumns.ID 的字段,如果包含则将其转换为 long 类型并赋给 dataId,否则将 INVALID_ID 赋给 dataId。 + if (mIsCreate || mDataId != dataId) {//检查是否正在创建新数据(mIsCreate 为 true),或者已有数据的 dataId 是否与新获取的 dataId 不同。 + mDiffDataValues.put(DataColumns.ID, dataId);//如果满足条件,则将 DataColumns.ID 和对应的 dataId 放入 mDiffDataValues 中。 } mDataId = dataId; @@ -130,42 +155,53 @@ public class SqlData { mDataContentData3 = dataContentData3; } + /** + * 将成员变量的值转换为JSON对象并返回。 + * @return JSONObject 对象包含了 SqlData 对象中各个成员变量的值,使用相应的键值表示。如果当前对象是新创建的,则打印错误日志并返回 null。 + * @throws JSONException 抛出的异常 + */ public JSONObject getContent() throws JSONException { if (mIsCreate) { Log.e(TAG, "it seems that we haven't created this in database yet"); return null; } JSONObject js = new JSONObject(); - js.put(DataColumns.ID, mDataId); - js.put(DataColumns.MIME_TYPE, mDataMimeType); + js.put(DataColumns.ID, mDataId);//将类的成员变量 mDataId 的值存储到 js 对象中,使用键名 DataColumns.ID。 + js.put(DataColumns.MIME_TYPE, mDataMimeType);//将类的成员变量 mDataMimeType 的值存储到 js 对象中,使用键名 DataColumns.MIME_TYPE js.put(DataColumns.CONTENT, mDataContent); js.put(DataColumns.DATA1, mDataContentData1); js.put(DataColumns.DATA3, mDataContentData3); return js; } + /** + * 提交数据的更改到数据库中。如果是新创建的数据,则将数据插入数据库并获取其ID;如果是已存在的数据,则根据mDiffDataValues对象中的差异字段值更新数据库中对应的记录。 + * @param noteId 便签的ID,表示要提交数据的便签的ID + * @param validateVersion 布尔值,表示是否需要验证版本号 + * @param version 长整型数,表示版本号 + */ public void commit(long noteId, boolean validateVersion, long version) { - if (mIsCreate) { + if (mIsCreate) {//如果数据是新创建的 if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) { mDiffDataValues.remove(DataColumns.ID); } - mDiffDataValues.put(DataColumns.NOTE_ID, noteId); - Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues); + mDiffDataValues.put(DataColumns.NOTE_ID, noteId); //设置便签的ID + Uri uri = mContentResolver.insert(Notes.CONTENT_DATA_URI, mDiffDataValues);//向数据库中插入数据 try { mDataId = Long.valueOf(uri.getPathSegments().get(1)); } catch (NumberFormatException e) { Log.e(TAG, "Get note id error :" + e.toString()); throw new ActionFailureException("create note failed"); } - } else { + } else {//如果不是新创建的数据 if (mDiffDataValues.size() > 0) { int result = 0; - if (!validateVersion) { + if (!validateVersion) {//如果不用验证版本,直接更新数据 result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null); - } else { + } else {//如果要验证版本,根据版本号更新数据 result = mContentResolver.update(ContentUris.withAppendedId( Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, " ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE @@ -179,10 +215,14 @@ public class SqlData { } } - mDiffDataValues.clear(); + mDiffDataValues.clear();//提交后清空数据 mIsCreate = false; } + /** + * 返回成员变量mDataId的值。 + * @return 成员信息的ID + */ public long getId() { return mDataId; }