精读批注第一次提交 #4

Merged
mth9uq3ve merged 5 commits from develop into master 1 year ago

Binary file not shown.

@ -22,42 +22,57 @@ import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Data;
import android.telephony.PhoneNumberUtils;
import android.util.Log;
import java.util.HashMap;
public class Contact {//定义一个Contact类类别标签为Contact包含一个用于存储用户信息的HashMap
private static HashMap<String, String> sContactCache;
private static final String TAG = "Contact";
//定义静态常量,用于查询指定联系人
private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER
+ ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
+ " AND " + Data.RAW_CONTACT_ID + " IN "
// 该代码是一个名为Contact的类用于获取联系人信息。
//代码中定义了一个静态的HashMap变量sContactCache用于缓存联系人信息。sContactCache的键是电话号码值是联系人姓名。
//定义了一个字符串常量CALLER_ID_SELECTION用于查询联系人信息的条件。该条件是通过拼接字符串而得到的包含了查询电话号码相等、数据类型为电话号码、联系人ID在指定范围内等条件。
//代码中定义了一个静态方法getContact用于根据电话号码获取联系人姓名。
public class Contact {
private static HashMap<String, String> sContactCache; // 缓存联系人信息
private static final String TAG = "Contact";//标签
private static final String CALLER_ID_SELECTION = "PHONE_NUMBERS_EQUAL(" + Phone.NUMBER
+ ",?) AND " + Data.MIMETYPE + "='" + Phone.CONTENT_ITEM_TYPE + "'"
+ " AND " + Data.RAW_CONTACT_ID + " IN "
+ "(SELECT raw_contact_id "
+ " FROM phone_lookup"
+ " WHERE min_match = '+')";
//定义一个静态方法getContact可以通过Contact对象以及电话号码查询联系人。
+ " WHERE min_match = '+')"; // 查询联系人信息的条件
/**
*
* @param context
* @param phoneNumber
* @return null
*/
// 该方法首先检查缓存中是否已有该电话号码对应的联系人姓名,如果有则返回缓存中的值。如果缓存中没有该电话号码对应的联系人姓名,则通过查询数据库来获取联系人姓名。
// 查询数据库的条件是根据电话号码生成的CALLER_ID_SELECTION。如果查询结果不为空且移动到第一条记录则从结果中提取联系人姓名并将其存入缓存中。如果查询结果为空则返回null。
public static String getContact(Context context, String phoneNumber) {
if(sContactCache == null) {//不存在这个联系人则新建一个存储信息
if (sContactCache == null) {
sContactCache = new HashMap<String, String>();
}
if(sContactCache.containsKey(phoneNumber)) {//如果已经包含电话号码作为关键字对应的用户
return sContactCache.get(phoneNumber);//直接返回用户的名字get返回名字
// 查找HashMap中是否已有phoneNumber信息
if (sContactCache.containsKey(phoneNumber)) {
return sContactCache.get(phoneNumber);//直接根据键值(电话号码)找到姓名
}
String selection = CALLER_ID_SELECTION.replace("+",
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));
PhoneNumberUtils.toCallerIDMinMatch(phoneNumber));//最小匹配原则查找电话号码
// 查找数据库中phoneNumber的信息
Cursor cursor = context.getContentResolver().query(
Data.CONTENT_URI,
new String [] { Phone.DISPLAY_NAME },
new String[] { Phone.DISPLAY_NAME },
selection,
new String[] { phoneNumber },
null);
// 判定查询结果
if (cursor != null && cursor.moveToFirst()) {
try {
// 找到相关信息
String name = cursor.getString(0);
sContactCache.put(phoneNumber, name);
sContactCache.put(phoneNumber, name);//放入缓存块
return name;
} catch (IndexOutOfBoundsException e) {
Log.e(TAG, " Cursor get string error " + e.toString());
@ -66,7 +81,8 @@ public class Contact {//定义一个Contact类类别标签为Contact包含
cursor.close();
}
} else {
Log.d(TAG, "No contact matched with number:" + phoneNumber);
// 未找到相关信息
Log.d(TAG, "No contact matched with number:" + phoneNumber);//给出反馈信息
return null;
}
}

@ -24,8 +24,8 @@ import net.micode.notes.tool.GTaskStringUtils;
import org.json.JSONException;
import org.json.JSONObject;
public class MetaData extends Task {
//主要是定义用于处理元数据
public class MetaData extends Task {//继承task是task的子类
private final static String TAG = MetaData.class.getSimpleName();
private String mRelatedGid = null;
@ -34,7 +34,7 @@ public class MetaData extends Task {
try {
metaInfo.put(GTaskStringUtils.META_HEAD_GTASK_ID, gid);
} catch (JSONException e) {
Log.e(TAG, "failed to put related gid");
Log.e(TAG, "failed to put related gid");//记录错误日志
}
setNotes(metaInfo.toString());
setName(GTaskStringUtils.META_NOTE_NAME);
@ -47,10 +47,10 @@ public class MetaData extends Task {
@Override
public boolean isWorthSaving() {
return getNotes() != null;
}
}//用于判断数据是否值得保存
@Override
public void setContentByRemoteJSON(JSONObject js) {//用远程的json
public void setContentByRemoteJSON(JSONObject js) {//用远程的json设置内容,基础操作元
super.setContentByRemoteJSON(js);
if (getNotes() != null) {
try {
@ -66,7 +66,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

@ -20,7 +20,7 @@ import android.database.Cursor;
import org.json.JSONObject;
public abstract class Node {
public abstract class Node {//主要定义一些获取属性值的方法
public static final int SYNC_ACTION_NONE = 0;
public static final int SYNC_ACTION_ADD_REMOTE = 1;
@ -38,6 +38,7 @@ public abstract class Node {
public static final int SYNC_ACTION_UPDATE_CONFLICT = 7;
public static final int SYNC_ACTION_ERROR = 8;
//为不同的同步类型添加调用编号
private String mGid;
@ -45,7 +46,7 @@ public abstract class Node {
private long mLastModified;
private boolean mDeleted;
private boolean mDeleted;//设置基础值,定义获取参数的方法
public Node() {
mGid = null;

@ -71,9 +71,9 @@ public class SqlData {
private ContentValues mDiffDataValues;
public SqlData(Context context) {
public SqlData(Context context) {//初始化对象,用于存储数据
mContentResolver = context.getContentResolver();
mIsCreate = true;
mIsCreate = true;//一类型的变量为true
mDataId = INVALID_ID;
mDataMimeType = DataConstants.NOTE;
mDataContent = "";
@ -82,14 +82,14 @@ public class SqlData {
mDiffDataValues = new ContentValues();
}
public SqlData(Context context, Cursor c) {
public SqlData(Context context, Cursor c) {//同样是存储数据另外定义支持冲cursor读入
mContentResolver = context.getContentResolver();
mIsCreate = false;
mIsCreate = false;//二类型的变量为false
loadFromCursor(c);
mDiffDataValues = new ContentValues();
}
private void loadFromCursor(Cursor c) {
private void loadFromCursor(Cursor c) {//上面用到的从cursor读取的函数从存储的各个列获取数据
mDataId = c.getLong(DATA_ID_COLUMN);
mDataMimeType = c.getString(DATA_MIME_TYPE_COLUMN);
mDataContent = c.getString(DATA_CONTENT_COLUMN);
@ -97,9 +97,9 @@ public class SqlData {
mDataContentData3 = c.getString(DATA_CONTENT_DATA_3_COLUMN);
}
public void setContent(JSONObject js) throws JSONException {
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;
if (mIsCreate || mDataId != dataId) {
public void setContent(@androidx.annotation.NonNull JSONObject js) throws JSONException {//获取json类型的参数并且根据它更新自定义的数据单元中的值
long dataId = js.has(DataColumns.ID) ? js.getLong(DataColumns.ID) : INVALID_ID;//如果有id直接赋值没有则需要在获取
if (mIsCreate || mDataId != dataId) {//初始未设置的数据单元通过它设置内容通过cursor产生的数据元可通过它完成更新
mDiffDataValues.put(DataColumns.ID, dataId);
}
mDataId = dataId;
@ -131,7 +131,7 @@ public class SqlData {
}
public JSONObject getContent() throws JSONException {
if (mIsCreate) {
if (mIsCreate) {//同样的只有通过cursor产生的数据单元可通过这个函数获取数据
Log.e(TAG, "it seems that we haven't created this in database yet");
return null;
}
@ -144,7 +144,7 @@ public class SqlData {
return js;
}
public void commit(long noteId, boolean validateVersion, long version) {
public void commit(long noteId, boolean validateVersion, long version) {//提交数据,并且打上类似于标签的版本号以及验证值
if (mIsCreate) {
if (mDataId == INVALID_ID && mDiffDataValues.containsKey(DataColumns.ID)) {
@ -162,10 +162,10 @@ public class SqlData {
} else {
if (mDiffDataValues.size() > 0) {
int result = 0;
if (!validateVersion) {
if (!validateVersion) { // 不验证版本的情况下直接使用ContentResolver更新指定ID的数据
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues, null, null);
} else {
} else { // 需要验证版本的情况下使用ContentResolver进行条件更新操作
result = mContentResolver.update(ContentUris.withAppendedId(
Notes.CONTENT_DATA_URI, mDataId), mDiffDataValues,
" ? in (SELECT " + NoteColumns.ID + " FROM " + TABLE.NOTE

@ -122,7 +122,7 @@ public class SqlNote {
private ArrayList<SqlData> mDataList;
public SqlNote(Context context) {
public SqlNote(Context context) {//定义数据单元存储数据
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = true;
@ -135,7 +135,7 @@ public class SqlNote {
mParentId = 0;
mSnippet = "";
mType = Notes.TYPE_NOTE;
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
mWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;//直接从设置的属性中获取值
mWidgetType = Notes.TYPE_WIDGET_INVALIDE;
mOriginParent = 0;
mVersion = 0;
@ -147,14 +147,14 @@ public class SqlNote {
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = false;
loadFromCursor(c);
loadFromCursor(c);//从cursor中直接获取变量值
mDataList = new ArrayList<SqlData>();
if (mType == Notes.TYPE_NOTE)
loadDataContent();
mDiffNoteValues = new ContentValues();
}
public SqlNote(Context context, long id) {
public SqlNote(Context context, long id) {//根据id初始化数据单元
mContext = context;
mContentResolver = context.getContentResolver();
mIsCreate = false;
@ -175,7 +175,7 @@ public class SqlNote {
}, null);
if (c != null) {
c.moveToNext();
loadFromCursor(c);
loadFromCursor(c);//通过调用减少重复代码编写
} else {
Log.w(TAG, "loadFromCursor: cursor = null");
}
@ -185,7 +185,7 @@ public class SqlNote {
}
}
private void loadFromCursor(Cursor c) {
private void loadFromCursor(Cursor c) {//直接使用get获得变量值
mId = c.getLong(ID_COLUMN);
mAlertDate = c.getLong(ALERTED_DATE_COLUMN);
mBgColorId = c.getInt(BG_COLOR_ID_COLUMN);
@ -200,7 +200,7 @@ public class SqlNote {
mVersion = c.getLong(VERSION_COLUMN);
}
private void loadDataContent() {
private void loadDataContent() {//这个函数判别查询的数据是否存在,并且读取到数据列表中存储
Cursor c = null;
mDataList.clear();
try {
@ -210,12 +210,12 @@ public class SqlNote {
}, null);
if (c != null) {
if (c.getCount() == 0) {
Log.w(TAG, "it seems that the note has not data");
Log.w(TAG, "it seems that the note has not data");//遇到文件为空抛出对应的异常
return;
}
while (c.moveToNext()) {
SqlData data = new SqlData(mContext, c);
mDataList.add(data);
mDataList.add(data);//向Datalist中加入读取到的数据
}
} else {
Log.w(TAG, "loadDataContent: cursor = null");
@ -226,7 +226,8 @@ public class SqlNote {
}
}
public boolean setContent(JSONObject js) {
public boolean setContent(JSONObject js) {//设置数据单元中变量的值
//如果所需的值存在,直接赋值使用,否则再先进行一步读取
try {
JSONObject note = js.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
if (note.getInt(NoteColumns.TYPE) == Notes.TYPE_SYSTEM) {
@ -359,7 +360,7 @@ public class SqlNote {
return true;
}
public JSONObject getContent() {
public JSONObject getContent() {//直接读取的方式将所需的数据读到对应变量
try {
JSONObject js = new JSONObject();
@ -412,6 +413,7 @@ public class SqlNote {
mDiffNoteValues.put(NoteColumns.PARENT_ID, id);
}
//定义一些简单的获取取值的方法
public void setGtaskId(String gid) {
mDiffNoteValues.put(NoteColumns.GTASK_ID, gid);
}
@ -440,7 +442,7 @@ public class SqlNote {
return mType == Notes.TYPE_NOTE;
}
public void commit(boolean validateVersion) {
public void commit(boolean validateVersion) {//将数据做一定修改提交
if (mIsCreate) {
if (mId == INVALID_ID && mDiffNoteValues.containsKey(NoteColumns.ID)) {
mDiffNoteValues.remove(NoteColumns.ID);

@ -32,7 +32,7 @@ import org.json.JSONException;
import org.json.JSONObject;
public class Task extends Node {
public class Task extends Node {//继承Node类的属性
private static final String TAG = Task.class.getSimpleName();
private boolean mCompleted;
@ -54,7 +54,7 @@ public class Task extends Node {
mMetaInfo = null;
}
public JSONObject getCreateAction(int actionId) {
public JSONObject getCreateAction(int actionId) {//创建一个初始的任务对象,并对它赋初值
JSONObject js = new JSONObject();
try {
@ -103,7 +103,7 @@ public class Task extends Node {
return js;
}
public JSONObject getUpdateAction(int actionId) {
public JSONObject getUpdateAction(int actionId) {//更新任务
JSONObject js = new JSONObject();
try {
@ -120,7 +120,7 @@ public class Task extends Node {
// entity_delta
JSONObject entity = new JSONObject();
entity.put(GTaskStringUtils.GTASK_JSON_NAME, getName());
if (getNotes() != null) {
if (getNotes() != null) {//如果笔记不为空,更新笔记
entity.put(GTaskStringUtils.GTASK_JSON_NOTES, getNotes());
}
entity.put(GTaskStringUtils.GTASK_JSON_DELETED, getDeleted());
@ -135,11 +135,11 @@ public class Task extends Node {
return js;
}
public void setContentByRemoteJSON(JSONObject js) {
public void setContentByRemoteJSON(JSONObject js) {//通过远端的json设置内容的值
if (js != null) {
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {//如果值已经被json对象所具备则直接进行设置
setGid(js.getString(GTaskStringUtils.GTASK_JSON_ID));
}
@ -175,7 +175,7 @@ public class Task extends Node {
}
}
public void setContentByLocalJSON(JSONObject js) {
public void setContentByLocalJSON(JSONObject js) {//通过本地的json文件来设置内容
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)
|| !js.has(GTaskStringUtils.META_HEAD_DATA)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
@ -204,7 +204,7 @@ public class Task extends Node {
}
}
public JSONObject getLocalJSONFromContent() {
public JSONObject getLocalJSONFromContent() {//通过本地的内容生成json文件
String name = getName();
try {
if (mMetaInfo == null) {
@ -216,7 +216,7 @@ public class Task extends Node {
JSONObject js = new JSONObject();
JSONObject note = new JSONObject();
JSONArray dataArray = new JSONArray();
JSONArray dataArray = new JSONArray();//声明所有所要用到的变量
JSONObject data = new JSONObject();
data.put(DataColumns.CONTENT, name);
dataArray.put(data);
@ -227,7 +227,7 @@ public class Task extends Node {
} else {
// synced task
JSONObject note = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);
JSONArray dataArray = mMetaInfo.getJSONArray(GTaskStringUtils.META_HEAD_DATA);//提取出所有的信息
for (int i = 0; i < dataArray.length(); i++) {
JSONObject data = dataArray.getJSONObject(i);
@ -258,11 +258,11 @@ public class Task extends Node {
}
}
public int getSyncAction(Cursor c) {
public int getSyncAction(Cursor c) {//同步缓存
try {
JSONObject noteInfo = null;
if (mMetaInfo != null && mMetaInfo.has(GTaskStringUtils.META_HEAD_NOTE)) {
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);
noteInfo = mMetaInfo.getJSONObject(GTaskStringUtils.META_HEAD_NOTE);//更新到最新的笔记信息
}
if (noteInfo == null) {
@ -311,14 +311,14 @@ public class Task extends Node {
return SYNC_ACTION_ERROR;
}
public boolean isWorthSaving() {
public boolean isWorthSaving() {//只要有信息就认为是值得保存的返回true
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;

@ -30,17 +30,17 @@ import org.json.JSONObject;
import java.util.ArrayList;
public class TaskList extends Node {
public class TaskList extends Node {//同Task一样继承了Node
private static final String TAG = TaskList.class.getSimpleName();
private int mIndex;
private ArrayList<Task> mChildren;
private ArrayList<Task> mChildren;//内部含有一个Task的列是任务的序列
public TaskList() {
super();
mChildren = new ArrayList<Task>();
mIndex = 1;
mIndex = 1;//初始化
}
public JSONObject getCreateAction(int actionId) {
@ -74,7 +74,7 @@ public class TaskList extends Node {
return js;
}
public JSONObject getUpdateAction(int actionId) {
public JSONObject getUpdateAction(int actionId) {//更新行动与Task中定义的基本一样
JSONObject js = new JSONObject();
try {
@ -104,7 +104,7 @@ public class TaskList extends Node {
}
public void setContentByRemoteJSON(JSONObject js) {
if (js != null) {
if (js != null) {//类似的通过远端更新内容
try {
// id
if (js.has(GTaskStringUtils.GTASK_JSON_ID)) {
@ -129,7 +129,7 @@ public class TaskList extends Node {
}
}
public void setContentByLocalJSON(JSONObject js) {
public void setContentByLocalJSON(JSONObject js) {//通过本地文件更新内容
if (js == null || !js.has(GTaskStringUtils.META_HEAD_NOTE)) {
Log.w(TAG, "setContentByLocalJSON: nothing is avaiable");
}
@ -215,26 +215,26 @@ public class TaskList extends Node {
return SYNC_ACTION_ERROR;
}
//以上都与task定义类似
public int getChildTaskCount() {
return mChildren.size();
}
public boolean addChildTask(Task task) {
boolean ret = false;
if (task != null && !mChildren.contains(task)) {
if (task != null && !mChildren.contains(task)) {//任务不为空,并且还不在列表中,则将其加入
ret = mChildren.add(task);
if (ret) {
if (ret) {//成功加入以后继续设置关系
// need to set prior sibling and parent
task.setPriorSibling(mChildren.isEmpty() ? null : mChildren
.get(mChildren.size() - 1));
task.setParent(this);
task.setParent(this);//设置任务的父子关系
}
}
return ret;
}
public boolean addChildTask(Task task, int index) {
public boolean addChildTask(Task task, int index) {//更进一步的实现在指定索引位置插入任务
if (index < 0 || index > mChildren.size()) {
Log.e(TAG, "add child task: invalid index");
return false;
@ -260,9 +260,9 @@ public class TaskList extends Node {
return true;
}
public boolean removeChildTask(Task task) {
public boolean removeChildTask(Task task) {//移除子任务
boolean ret = false;
int index = mChildren.indexOf(task);
int index = mChildren.indexOf(task);//查找其索引
if (index != -1) {
ret = mChildren.remove(task);
@ -281,7 +281,7 @@ public class TaskList extends Node {
return ret;
}
public boolean moveChildTask(Task task, int index) {
public boolean moveChildTask(Task task, int index) {//定向移除对应位置的任务
if (index < 0 || index >= mChildren.size()) {
Log.e(TAG, "move child task: invalid index");
@ -299,7 +299,7 @@ public class TaskList extends Node {
return (removeChildTask(task) && addChildTask(task, index));
}
public Task findChildTaskByGid(String gid) {
public Task findChildTaskByGid(String gid) {//通过Gid查找任务
for (int i = 0; i < mChildren.size(); i++) {
Task t = mChildren.get(i);
if (t.getGid().equals(gid)) {
@ -309,7 +309,7 @@ public class TaskList extends Node {
return null;
}
public int getChildTaskIndex(Task task) {
public int getChildTaskIndex(Task task) {//获取任务对应的索引
return mChildren.indexOf(task);
}
@ -323,7 +323,7 @@ public class TaskList extends Node {
public Task getChilTaskByGid(String gid) {
for (Task task : mChildren) {
if (task.getGid().equals(gid))
if (task.getGid().equals(gid))//找到一个gid相符的即为所要的任务
return task;
}
return null;

@ -15,19 +15,28 @@
*/
package net.micode.notes.gtask.exception;
/**
* @method: ActionFailureException
* @description:ActionFailureException RuntimeException
*
* serialVersionUID
* @date: 11:05
* @author: Xia Yanbo
*/
public class ActionFailureException extends RuntimeException {//异常处理程序,定义了全部可能参数下抛出错误
private static final long serialVersionUID = 4425249765923293627L;
public class ActionFailureException extends RuntimeException {
private static final long serialVersionUID = 4425249765923293627L;//序列化,用于验证版本一致性
//构造方法
public ActionFailureException() {
super();
super();//用构造方法赋初值,调用父类无参数的构造方法
}
//构造方法
public ActionFailureException(String paramString) {
super(paramString);
super(paramString);//调用父类有参数的构造方法
}
//构造方法
public ActionFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}
}

@ -15,18 +15,29 @@
*/
package net.micode.notes.gtask.exception;//调用完成异常处理
/**
* @method: NetworkFailureException
* @description:NetworkFailureException Exception
*
* //定义了私有参数serialVersionUID是序列化用于验证版本一致性
* @date: 11:07
* @author: Xia Yanbo
* @param:
* @param:
* @param:
*/
public class NetworkFailureException extends Exception {
private static final long serialVersionUID = 2107610287180234136L;
private static final long serialVersionUID = 2107610287180234136L;//序列化,用于验证版本一致性
//构造方法
public NetworkFailureException() {
super();
super();//用构造方法赋初值,调用父类无参数的构造方法
}
//构造方法
public NetworkFailureException(String paramString) {
super(paramString);
super(paramString);//调用父类有参数的构造方法
}
//构造方法
public NetworkFailureException(String paramString, Throwable paramThrowable) {
super(paramString, paramThrowable);
}

@ -29,10 +29,21 @@ import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;
/**
* @method: GTaskASyncTask
* @description:GTaskASyncTask AsyncTask
*
* 4
* mcontext 访context
* mOnCompleteListener
* mNotifiManager mTaskManager
* @date: 9:01
* @author: Xia Yanbo
*/
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;//序列化,用于验证版本
//声明定义一个接口OnCompleteListener实现放在后面
public interface OnCompleteListener {
void onComplete();
}
@ -44,7 +55,16 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private GTaskManager mTaskManager;
private OnCompleteListener mOnCompleteListener;
/**
* @method: GTaskASyncTask
* @description:GTaskASyncTask
* @date: 16:11
* @author: Xia Yanbo
* @param: mcontext 访context
* @param: mOnCompleteListener
* @param: mNotifiManager
* @param: mTaskManager
*/
public GTaskASyncTask(Context context, OnCompleteListener listener) {
mContext = context;
mOnCompleteListener = listener;
@ -52,22 +72,42 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
.getSystemService(Context.NOTIFICATION_SERVICE);
mTaskManager = GTaskManager.getInstance();
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:32
* @author: Xia Yanbo
*/
public void cancelSync() {
mTaskManager.cancelSync();
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:33
* @author: Xia Yanbo
* @param: message
*/
public void publishProgess(String message) {
publishProgress(new String[] {
message
});
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:35
* @author: Xia Yanbo
* @param:tickerIdID
* @param:content
* @return:NULL
*/
private void showNotification(int tickerId, String content) {
Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS;
notification.flags = Notification.FLAG_AUTO_CANCEL;
notification.flags = Notification.FLAG_AUTO_CANCEL;//打上标识,用于判断发送报错信息和通知操作等
PendingIntent pendingIntent;
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
@ -79,24 +119,43 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
}
// notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
// pendingIntent);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);//直接调用父类的方法
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:46
* @author: Xia Yanbo
* @return:
*/
@Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext)));
.getSyncAccountName(mContext)));//获取用户的状态信息
return mTaskManager.sync(mContext, this);
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:50
* @author: Xia Yanbo
* @param:Progress
*/
@Override
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);
if (mContext instanceof GTaskSyncService) {
showNotification(R.string.ticker_syncing, progress[0]);//显示正在进行同步操作的通知
if (mContext instanceof GTaskSyncService) {//检查是否是GTaskSyncService的实例。
((GTaskSyncService) mContext).sendBroadcast(progress[0]);
// 如果是就调用该服务的sendBroadcast方法发送广播通知其他组件同步的进度。
}
}
/**
* @method: GTaskASyncTask
* @description:
* @date: 8:57
* @author: Xia Yanbo
* @param:result
*/
@Override
protected void onPostExecute(Integer result) {
if (result == GTaskManager.STATE_SUCCESS) {
@ -111,7 +170,7 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
showNotification(R.string.ticker_cancel, mContext
.getString(R.string.error_sync_cancelled));
}
if (mOnCompleteListener != null) {
if (mOnCompleteListener != null) {//如果监听到了报文,创建一个新的线程来通知任务完成(减少主进程时间浪费)
new Thread(new Runnable() {
public void run() {

@ -36,16 +36,26 @@ import net.micode.notes.R;
import java.util.HashMap;
import java.util.Map;
/**
* @classname: NoteEditText
* @methodname
* @description:
* @date: 2023/12/24 9:22
* @author: Xia Yanbo
* @param:
* @param:
* @param:
* @return:
*/
public class NoteEditText extends EditText {
private static final String TAG = "NoteEditText";
private int mIndex;
private static final String TAG = "NoteEditText";//标签,分类接收特定信息
private int mIndex;//声明文本的索引
private int mSelectionStartBeforeDelete;
//声明字符串常量,标志电话、网址、邮件
private static final String SCHEME_TEL = "tel:" ;
private static final String SCHEME_HTTP = "http:" ;
private static final String SCHEME_EMAIL = "mailto:" ;
//设置映射,将文本内容拼接成完整的网址
private static final Map<String, Integer> sSchemaActionResMap = new HashMap<String, Integer>();
static {
sSchemaActionResMap.put(SCHEME_TEL, R.string.note_link_tel);
@ -55,53 +65,65 @@ public class NoteEditText extends EditText {
/**
* Call by the {@link NoteEditActivity} to delete or add edit text
* NoteEditActivity
*/
public interface OnTextViewChangeListener {
/**
* Delete current edit text when {@link KeyEvent#KEYCODE_DEL} happens
* and the text is null
* delete
*/
void onEditTextDelete(int index, String text);
/**
* Add edit text after current edit text when {@link KeyEvent#KEYCODE_ENTER}
* happen
* enter
*/
void onEditTextEnter(int index, String text);
/**
* Hide or show item option when text change
*
*/
void onTextChange(int index, boolean hasText);
}
//声明文本视图变化的监听器
private OnTextViewChangeListener mOnTextViewChangeListener;
//实例化NoteEditText对象
public NoteEditText(Context context) {
super(context, null);
mIndex = 0;
}
//为本本编辑设置一个索引
public void setIndex(int index) {
mIndex = index;
}
//直接调用父类,定义好文本视图变化的监听器
public void setOnTextViewChangeListener(OnTextViewChangeListener listener) {
mOnTextViewChangeListener = listener;
}
//NoteEditText的构造函数通过文本编辑风格的参数集实例化
public NoteEditText(Context context, AttributeSet attrs) {
super(context, attrs, android.R.attr.editTextStyle);
}
//NoteEditText的构造函数通过文本编辑风格的参数集实例化支持用户自定义风格
public NoteEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
super(context, attrs, defStyle);//允许自定义风格
// TODO Auto-generated constructor stub
}
/**
* @classname: NoteEditText
* @methodname onTouchEvent
* @description:
* @date: 2023/12/24 10:05
* @author: Xia Yanbo
* @param:event
* @return:boolean
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
switch (event.getAction()) {//对动作事件进行分类的判别
case MotionEvent.ACTION_DOWN:
int x = (int) event.getX();
@ -112,15 +134,24 @@ public class NoteEditText extends EditText {
y += getScrollY();
Layout layout = getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
int line = layout.getLineForVertical(y);//直接获取行数
int off = layout.getOffsetForHorizontal(line, x);//从边界起数获得偏移
Selection.setSelection(getText(), off);
break;
}
return super.onTouchEvent(event);
return super.onTouchEvent(event);//再调用父类的方法进行后续的处理
}
/**
* @classname: NoteEditText
* @methodname onKeyDown
* @description:
* @date: 2023/12/24 10:15
* @author: Xia Yanbo
* @param:keyCode
* @param:event
* @return:boolean
*/
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
@ -137,7 +168,16 @@ public class NoteEditText extends EditText {
}
return super.onKeyDown(keyCode, event);
}
/**
* @classname: NoteEditText
* @methodname onKeyUp
* @description:
* @date: 2023/12/24 10:15
* @author: Xia Yanbo
* @param:keyCode
* @param:event
* @return:boolean
*/
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
switch(keyCode) {
@ -166,11 +206,20 @@ public class NoteEditText extends EditText {
}
return super.onKeyUp(keyCode, event);
}
/**
* @classname: NoteEditText
* @methodname onFocusChanged
* @description:
* @date: 2023/12/24 10:25
* @author: Xia Yanbo
* @param:focused
* @param:direction
* @param:reviouslyFocusedRect
*/
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
if (mOnTextViewChangeListener != null) {
if (!focused && TextUtils.isEmpty(getText())) {
if (!focused && TextUtils.isEmpty(getText())) {//当没有输入,关注的视图也发生改变,设置隐藏
mOnTextViewChangeListener.onTextChange(mIndex, false);
} else {
mOnTextViewChangeListener.onTextChange(mIndex, true);
@ -178,19 +227,27 @@ public class NoteEditText extends EditText {
}
super.onFocusChanged(focused, direction, previouslyFocusedRect);
}
/**
* @classname: NoteEditText
* @methodname onCreateContextMenu
* @description:
* @date: 2023/12/24 10:34
* @author: Xia Yanbo
* @param:contextMenu
*/
@Override
protected void onCreateContextMenu(ContextMenu menu) {
if (getText() instanceof Spanned) {
int selStart = getSelectionStart();
int selEnd = getSelectionEnd();
if (getText() instanceof Spanned) {//检查文本的类型 Spanned是一个接口
int selStart = getSelectionStart();//所选择文本的开始位置
int selEnd = getSelectionEnd();//所选择文本的结束位置
//确定选择开始的较小值和较大值,方便直接做差
int min = Math.min(selStart, selEnd);
int max = Math.max(selStart, selEnd);
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);
//获取选择的文本范围内获取所有的 URLSpan 对象。URLSpan 是用于表示文本中的链接的。
final URLSpan[] urls = ((Spanned) getText()).getSpans(min, max, URLSpan.class);//获取范围
if (urls.length == 1) {
int defaultResId = 0;
//根据URL获取资源
for(String schema: sSchemaActionResMap.keySet()) {
if(urls[0].getURL().indexOf(schema) >= 0) {
defaultResId = sSchemaActionResMap.get(schema);
@ -201,9 +258,10 @@ public class NoteEditText extends EditText {
if (defaultResId == 0) {
defaultResId = R.string.note_link_other;
}
//添加菜单项
menu.add(0, 0, 0, defaultResId).setOnMenuItemClickListener(
new OnMenuItemClickListener() {
//设置监听器,放菜单项被点击,触发链接
public boolean onMenuItemClick(MenuItem item) {
// goto a new intent
urls[0].onClick(NoteEditText.this);
@ -212,6 +270,6 @@ public class NoteEditText extends EditText {
});
}
}
super.onCreateContextMenu(menu);
super.onCreateContextMenu(menu);//调用父类方法
}
}

Loading…
Cancel
Save