diff --git a/branch2.txt b/branch2.txt new file mode 100644 index 0000000..c39e09f --- /dev/null +++ b/branch2.txt @@ -0,0 +1 @@ +66666 \ No newline at end of file diff --git a/doc/1.txt b/doc/1.txt new file mode 100644 index 0000000..e69de29 diff --git a/master b/master new file mode 100644 index 0000000..66dc905 --- /dev/null +++ b/master @@ -0,0 +1 @@ +undefined \ No newline at end of file diff --git a/src/net/micode/notes/gtask/exception/ActionFailureException.java b/src/net/micode/notes/gtask/exception/ActionFailureException.java index 15504be..526dcc2 100644 --- a/src/net/micode/notes/gtask/exception/ActionFailureException.java +++ b/src/net/micode/notes/gtask/exception/ActionFailureException.java @@ -16,18 +16,35 @@ package net.micode.notes.gtask.exception; +/* + * ActionFailureException类用于表示在执行操作时发生的失败情况。 + * 它继承自RuntimeException,用于在操作失败时抛出异常。 + */ public class ActionFailureException extends RuntimeException { + // 序列化版本UID,用于标识类的版本 private static final long serialVersionUID = 4425249765923293627L; + /* + * 构造一个没有任何消息的ActionFailureException对象。 + */ public ActionFailureException() { super(); } + /* + * 构造一个带有指定消息的ActionFailureException对象。 + * @param paramString 异常消息 + */ public ActionFailureException(String paramString) { super(paramString); } + /* + * 构造一个带有指定消息和原因的ActionFailureException对象。 + * @param paramString 异常消息 + * @param paramThrowable 异常原因 + */ public ActionFailureException(String paramString, Throwable paramThrowable) { super(paramString, paramThrowable); } -} +} \ No newline at end of file diff --git a/src/net/micode/notes/gtask/exception/NetworkFailureException.java b/src/net/micode/notes/gtask/exception/NetworkFailureException.java index b08cfb1..083cf62 100644 --- a/src/net/micode/notes/gtask/exception/NetworkFailureException.java +++ b/src/net/micode/notes/gtask/exception/NetworkFailureException.java @@ -16,18 +16,35 @@ package net.micode.notes.gtask.exception; +/* + * NetworkFailureException类用于表示在执行网络操作时发生的失败情况。 + * 它继承自Exception,用于在在网络请求失败时抛出异常。 + */ public class NetworkFailureException extends Exception { + // 序列化版本UID,用于标识类的版本 private static final long serialVersionUID = 2107610287180234136L; + /* + * 构造一个没有任何消息的NetworkFailureException对象。 + */ public NetworkFailureException() { super(); } + /* + * 构造一个带有指定消息的NetworkFailureException对象。 + * @param paramString 异常消息 + */ public NetworkFailureException(String paramString) { super(paramString); } + /* + * 构造一个带有指定消息和原因的NetworkFailureException对象。 + * @param paramString 异常消息 + * @param paramThrowable 异常原因 + */ public NetworkFailureException(String paramString, Throwable paramThrowable) { super(paramString, paramThrowable); } -} +} \ No newline at end of file diff --git a/src/net/micode/notes/gtask/remote/GTaskASyncTask.java b/src/net/micode/notes/gtask/remote/GTaskASyncTask.java index b3b61e7..7926415 100644 --- a/src/net/micode/notes/gtask/remote/GTaskASyncTask.java +++ b/src/net/micode/notes/gtask/remote/GTaskASyncTask.java @@ -1,123 +1,137 @@ - /* - * 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. + * 版权声明:此处声明代码的版权属于 MiCode 开放源代码社区,并指定了许可协议为 Apache License 2.0。 + * 提供了许可协议的获取链接。 + * 强调除非适用法律要求或书面同意,否则软件按 “原样” 分发,不提供任何形式的明示或暗示保证。 + * 并指出许可协议中关于权限和限制的具体语言。 */ package net.micode.notes.gtask.remote; -import android.app.Notification; -import android.app.NotificationManager; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.os.AsyncTask; +import android.app.Notification; // 导入 Notification 类,用于创建通知 +import android.app.NotificationManager; // 导入 NotificationManager 类,用于管理通知 +import android.app.PendingIntent; // 导入 PendingIntent 类,用于创建待定意图 +import android.content.Context; // 导入 Context 类,用于获取系统服务等 +import android.content.Intent; // 导入 Intent 类,用于启动活动等 +import android.os.AsyncTask; // 导入 AsyncTask 类,用于在后台线程执行耗时操作 -import net.micode.notes.R; -import net.micode.notes.ui.NotesListActivity; -import net.micode.notes.ui.NotesPreferenceActivity; +import net.micode.notes.R; // 导入资源文件 +import net.micode.notes.ui.NotesListActivity; // 导入笔记列表活动类 +import net.micode.notes.ui.NotesPreferenceActivity; // 导入笔记偏好设置活动类 +/** + * GTaskASyncTask 类,继承自 AsyncTask,用于在后台线程执行 Google Tasks 同步操作。 + */ public class GTaskASyncTask extends AsyncTask { - private static int GTASK_SYNC_NOTIFICATION_ID = 5234235; + private static int GTASK_SYNC_NOTIFICATION_ID = 5234235; // 定义同步通知的 ID + /** + * 定义同步完成的回调接口,用于在同步完成后执行相应操作。 + */ public interface OnCompleteListener { - void onComplete(); + void onComplete(); // 定义 onComplete 方法,具体实现由调用者提供 } - private Context mContext; - - private NotificationManager mNotifiManager; - - private GTaskManager mTaskManager; - - private OnCompleteListener mOnCompleteListener; - + private Context mContext; // 应用程序上下文 + private NotificationManager mNotifiManager; // 通知管理器 + private GTaskManager mTaskManager; // Google Tasks 管理器 + private OnCompleteListener mOnCompleteListener; // 同步完成回调接口实例 + + /** + * 构造函数,用于初始化 GTaskASyncTask 对象。 + * + * @param context 应用程序上下文 + * @param listener 同步完成回调接口实例 + */ public GTaskASyncTask(Context context, OnCompleteListener listener) { - mContext = context; - mOnCompleteListener = listener; + mContext = context; // 保存上下文 + mOnCompleteListener = listener; // 保存回调接口实例 mNotifiManager = (NotificationManager) mContext - .getSystemService(Context.NOTIFICATION_SERVICE); - mTaskManager = GTaskManager.getInstance(); + .getSystemService(Context.NOTIFICATION_SERVICE); // 获取通知管理器实例 + mTaskManager = GTaskManager.getInstance(); // 获取 Google Tasks 管理器实例 } + /** + * 取消同步操作。 + */ public void cancelSync() { - mTaskManager.cancelSync(); + mTaskManager.cancelSync(); // 调用 Google Tasks 管理器的 cancelSync 方法取消同步 } + /** + * 发布进度信息。 + * + * @param message 进度信息 + */ public void publishProgess(String message) { - publishProgress(new String[] { - message + publishProgress(new String[]{ // 调用 AsyncTask 的 publishProgress 方法发布进度 + message }); } + /** + * 显示通知。 + * + * @param tickerId 通知的 ticker 文本资源 ID + * @param content 通知内容 + */ 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 notification = new Notification(R.drawable.notification, mContext // 创建通知对象 + .getString(tickerId), System.currentTimeMillis()); // 设置通知图标、ticker 文本和时间 + notification.defaults = Notification.DEFAULT_LIGHTS; // 设置默认通知灯光 + notification.flags = Notification.FLAG_AUTO_CANCEL; // 设置通知点击后自动取消 PendingIntent pendingIntent; - if (tickerId != R.string.ticker_success) { - pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + if (tickerId != R.string.ticker_success) { // 如果不是成功通知 + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, // 创建指向 NotesPreferenceActivity 的待定意图 NotesPreferenceActivity.class), 0); - } else { - pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, + } else { // 如果是成功通知 + pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext, // 创建指向 NotesListActivity 的待定意图 NotesListActivity.class), 0); } - notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content, + 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); // 发出通知 } + /** + * 在后台线程执行同步操作。 + * + * @param unused 未使用的参数 + * @return 同步操作的结果状态码 + */ @Override protected Integer doInBackground(Void... unused) { - publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity + publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity // 发布登录进度信息 .getSyncAccountName(mContext))); - return mTaskManager.sync(mContext, this); + return mTaskManager.sync(mContext, this); // 执行同步操作并返回结果状态码 } + /** + * 在 UI 线程更新进度。 + * + * @param progress 进度信息数组 + */ @Override protected void onProgressUpdate(String... progress) { - showNotification(R.string.ticker_syncing, progress[0]); - if (mContext instanceof GTaskSyncService) { - ((GTaskSyncService) mContext).sendBroadcast(progress[0]); + showNotification(R.string.ticker_syncing, progress[0]); // 显示同步中通知 + if (mContext instanceof GTaskSyncService) { // 如果上下文是 GTaskSyncService 实例 + ((GTaskSyncService) mContext).sendBroadcast(progress[0]); // 发送广播更新进度 } } + /** + * 在 UI 线程处理同步结果。 + * + * @param result 同步操作的结果状态码 + */ @Override protected void onPostExecute(Integer result) { - if (result == GTaskManager.STATE_SUCCESS) { - showNotification(R.string.ticker_success, mContext.getString( + if (result == GTaskManager.STATE_SUCCESS) { // 如果同步成功 + showNotification(R.string.ticker_success, mContext.getString( // 显示成功通知 R.string.success_sync_account, mTaskManager.getSyncAccount())); - NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); - } else if (result == GTaskManager.STATE_NETWORK_ERROR) { - showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_network)); - } else if (result == GTaskManager.STATE_INTERNAL_ERROR) { - showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_internal)); - } else if (result == GTaskManager.STATE_SYNC_CANCELLED) { - showNotification(R.string.ticker_cancel, mContext - .getString(R.string.error_sync_cancelled)); - } - if (mOnCompleteListener != null) { - new Thread(new Runnable() { + NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis()); // 更新最后同步时间 - public void run() { - mOnCompleteListener.onComplete(); - } - }).start(); - } - } -} + } else if (result == GTaskManager.STATE_NETWORK_ERROR) { // 如果是网络错误 + showNotification(R.string.ticker_fail, mContext.getString(R.string.error_sync_n \ No newline at end of file diff --git a/src/net/micode/notes/gtask/remote/GTaskClient.java b/src/net/micode/notes/gtask/remote/GTaskClient.java index c67dfdf..5c04aa7 100644 --- a/src/net/micode/notes/gtask/remote/GTaskClient.java +++ b/src/net/micode/notes/gtask/remote/GTaskClient.java @@ -1,95 +1,82 @@ /* - * 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. + * 版权声明:此处声明代码的版权属于 MiCode 开放源代码社区,并指定了许可协议为 Apache License 2.0。 + * 提供了许可协议的获取链接。 + * 强调除非适用法律要求或书面同意,否则软件按 “原样” 分发,不提供任何形式的明示或暗示保证。 + * 并指出许可协议中关于权限和限制的具体语言。 */ package net.micode.notes.gtask.remote; -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AccountManagerFuture; -import android.app.Activity; -import android.os.Bundle; -import android.text.TextUtils; -import android.util.Log; - -import net.micode.notes.gtask.data.Node; -import net.micode.notes.gtask.data.Task; -import net.micode.notes.gtask.data.TaskList; -import net.micode.notes.gtask.exception.ActionFailureException; -import net.micode.notes.gtask.exception.NetworkFailureException; -import net.micode.notes.tool.GTaskStringUtils; -import net.micode.notes.ui.NotesPreferenceActivity; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.cookie.Cookie; -import org.apache.http.impl.client.BasicCookieStore; -import org.apache.http.impl.client.DefaultHttpClient; -import org.apache.http.message.BasicNameValuePair; -import org.apache.http.params.BasicHttpParams; -import org.apache.http.params.HttpConnectionParams; -import org.apache.http.params.HttpParams; -import org.apache.http.params.HttpProtocolParams; -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.LinkedList; -import java.util.List; -import java.util.zip.GZIPInputStream; -import java.util.zip.Inflater; -import java.util.zip.InflaterInputStream; - - +import android.accounts.Account; // 导入 Account 类,用于表示用户账户 +import android.accounts.AccountManager; // 导入 AccountManager 类,用于管理账户 +import android.accounts.AccountManagerFuture; // 导入 AccountManagerFuture 类,用于异步获取账户信息 +import android.app.Activity; // 导入 Activity 类,用于表示 Android 应用程序的活动 +import android.os.Bundle; // 导入 Bundle 类,用于传递数据 +import android.text.TextUtils; // 导入 TextUtils 类,用于处理文本操作 +import android.util.Log; // 导入 Log 类,用于记录日志信息 + +import net.micode.notes.gtask.data.Node; // 导入 Node 类,表示任务节点 +import net.micode.notes.gtask.data.Task; // 导入 Task 类,表示任务 +import net.micode.notes.gtask.data.TaskList; // 导入 TaskList 类,表示任务列表 +import net.micode.notes.gtask.exception.ActionFailureException; // 导入 ActionFailureException 类,表示操作失败异常 +import net.micode.notes.gtask.exception.NetworkFailureException; // 导入 NetworkFailureException 类,表示网络失败异常 +import net.micode.notes.tool.GTaskStringUtils; // 导入 GTaskStringUtils 类,提供字符串处理工具 +import net.micode.notes.ui.NotesPreferenceActivity; // 导入 NotesPreferenceActivity 类,用于处理笔记偏好设置 + +import org.apache.http.HttpEntity; // 导入 HttpEntity 类,用于表示 HTTP 响应实体 +import org.apache.http.HttpResponse; // 导入 HttpResponse 类,用于表示 HTTP 响应 +import org.apache.http.client.ClientProtocolException; // 导入 ClientProtocolException 类,表示客户端协议异常 +import org.apache.http.client.entity.UrlEncodedFormEntity; // 导入 UrlEncodedFormEntity 类,用于编码表单实体 +import org.apache.http.client.methods.HttpGet; // 导入 HttpGet 类,用于发送 HTTP GET 请求 +import org.apache.http.client.methods.HttpPost; // 导入 HttpPost 类,用于发送 HTTP POST 请求 +import org.apache.http.cookie.Cookie; // 导入 Cookie 类,用于表示 HTTP Cookie +import org.apache.http.impl.client.BasicCookieStore; // 导入 BasicCookieStore 类,用于存储 Cookie +import org.apache.http.impl.client.DefaultHttpClient; // 导入 DefaultHttpClient 类,用于创建 HTTP 客户端 +import org.apache.http.message.BasicNameValuePair; // 导入 BasicNameValuePair 类,用于表示键值对 +import org.apache.http.params.BasicHttpParams; // 导入 BasicHttpParams 类,用于设置 HTTP 参数 +import org.apache.http.params.HttpConnectionParams; // 导入 HttpConnectionParams 类,用于设置连接参数 +import org.apache.http.params.HttpProtocolParams; // 导入 HttpProtocolParams 类,用于设置协议参数 +import org.json.JSONArray; // 导入 JSONArray 类,用于处理 JSON 数组 +import org.json.JSONException; // 导入 JSONException 类,表示 JSON 相关异常 +import org.json.JSONObject; // 导入 JSONObject 类,用于处理 JSON 对象 + +import java.io.BufferedReader; // 导入 BufferedReader 类,用于读取文本流 +import java.io.IOException; // 导入 IOException 类,表示 I/O 异常 +import java.io.InputStream; // 导入 InputStream 类,表示输入流 +import java.io.InputStreamReader; // 导入 InputStreamReader 类,用于将输入流转换为字符流 +import java.util.LinkedList; // 导入 LinkedList 类,用于创建链表 +import java.util.List; // 导入 List 接口,用于表示列表 +import java.util.zip.GZIPInputStream; // 导入 GZIPInputStream 类,用于处理 GZIP 压缩流 +import java.util.zip.Inflater; // 导入 Inflater 类,用于解压缩 +import java.util.zip.InflaterInputStream; // 导入 InflaterInputStream 类,用于解压缩流 + + +/** + * GTaskClient 类,用于与 Google Tasks 服务进行交互,执行任务和任务列表的创建、更新、删除等操作。 + */ public class GTaskClient { - private static final String TAG = GTaskClient.class.getSimpleName(); - - private static final String GTASK_URL = "https://mail.google.com/tasks/"; - - private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig"; - - private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig"; - - private static GTaskClient mInstance = null; - - private DefaultHttpClient mHttpClient; - - private String mGetUrl; - - private String mPostUrl; - - private long mClientVersion; - - private boolean mLoggedin; - private long mLastLoginTime; + private static final String TAG = GTaskClient.class.getSimpleName(); // 定义日志标签 - private int mActionId; + private static final String GTASK_URL = "https://mail.google.com/tasks/ "; // 定义 Google Tasks 基础 URL + private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig "; // 定义 Google Tasks GET 请求 URL + private static final String GTASK_POST_URL = "https://mail.google.com/tasks/r/ig "; // 定义 Google Tasks POST 请求 URL - private Account mAccount; + private static GTaskClient mInstance = null; // 单例实例 - private JSONArray mUpdateArray; + private DefaultHttpClient mHttpClient; // HTTP 客户端 + private String mGetUrl; // GET 请求 URL + private String mPostUrl; // POST 请求 URL + private long mClientVersion; // 客户端版本 + private boolean mLoggedin; // 登录状态 + private long mLastLoginTime; // 最后登录时间 + private int mActionId; // 操作 ID + private Account mAccount; // 用户账户 + private JSONArray mUpdateArray; // 更新操作数组 + /** + * 构造函数,私有化以实现单例模式。 + */ private GTaskClient() { mHttpClient = null; mGetUrl = GTASK_GET_URL; @@ -102,6 +89,11 @@ public class GTaskClient { mUpdateArray = null; } + /** + * 获取 GTaskClient 单例实例。 + * + * @return 单例实例 + */ public static synchronized GTaskClient getInstance() { if (mInstance == null) { mInstance = new GTaskClient(); @@ -109,18 +101,23 @@ public class GTaskClient { return mInstance; } + /** + * 登录 Google Tasks 服务。 + * + * @param activity 当前活动 + * @return 登录是否成功 + */ public boolean login(Activity activity) { - // we suppose that the cookie would expire after 5 minutes - // then we need to re-login - final long interval = 1000 * 60 * 5; + // 检查是否需要重新登录 + final long interval = 1000 * 60 * 5; // 5 分钟间隔 if (mLastLoginTime + interval < System.currentTimeMillis()) { mLoggedin = false; } - // need to re-login after account switch + // 如果切换了账户,需要重新登录 if (mLoggedin && !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity - .getSyncAccountName(activity))) { + .getSyncAccountName(activity))) { mLoggedin = false; } @@ -136,7 +133,7 @@ public class GTaskClient { return false; } - // login with custom domain if necessary + // 如果是自定义域名账户,尝试使用自定义域名登录 if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() .endsWith("googlemail.com"))) { StringBuilder url = new StringBuilder(GTASK_URL).append("a/"); @@ -151,7 +148,7 @@ public class GTaskClient { } } - // try to login with google official url + // 尝试使用 Google 官方 URL 登录 if (!mLoggedin) { mGetUrl = GTASK_GET_URL; mPostUrl = GTASK_POST_URL; @@ -164,6 +161,13 @@ public class GTaskClient { return true; } + /** + * 登录 Google 账户并获取认证令牌。 + * + * @param activity 当前活动 + * @param invalidateToken 是否使令牌失效 + * @return 认证令牌 + */ private String loginGoogleAccount(Activity activity, boolean invalidateToken) { String authToken; AccountManager accountManager = AccountManager.get(activity); @@ -189,7 +193,7 @@ public class GTaskClient { return null; } - // get the token now + // 获取认证令牌 AccountManagerFuture accountManagerFuture = accountManager.getAuthToken(account, "goanna_mobile", null, activity, null, null); try { @@ -207,10 +211,16 @@ public class GTaskClient { return authToken; } + /** + * 尝试登录 Google Tasks 服务。 + * + * @param activity 当前活动 + * @param authToken 认证令牌 + * @return 登录是否成功 + */ private boolean tryToLoginGtask(Activity activity, String authToken) { if (!loginGtask(authToken)) { - // maybe the auth token is out of date, now let's invalidate the - // token and try again + // 如果认证令牌过期,重新获取令牌并再次尝试登录 authToken = loginGoogleAccount(activity, true); if (authToken == null) { Log.e(TAG, "login google account failed"); @@ -225,6 +235,12 @@ public class GTaskClient { return true; } + /** + * 登录 Google Tasks 服务。 + * + * @param authToken 认证令牌 + * @return 登录是否成功 + */ private boolean loginGtask(String authToken) { int timeoutConnection = 10000; int timeoutSocket = 15000; @@ -236,14 +252,12 @@ public class GTaskClient { mHttpClient.setCookieStore(localBasicCookieStore); HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false); - // login gtask try { String loginUrl = mGetUrl + "?auth=" + authToken; HttpGet httpGet = new HttpGet(loginUrl); - HttpResponse response = null; - response = mHttpClient.execute(httpGet); + HttpResponse response = mHttpClient.execute(httpGet); - // get the cookie now + // 获取 Cookie List cookies = mHttpClient.getCookieStore().getCookies(); boolean hasAuthCookie = false; for (Cookie cookie : cookies) { @@ -255,7 +269,7 @@ public class GTaskClient { Log.w(TAG, "it seems that there is no auth cookie"); } - // get the client version + // 获取客户端版本 String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -272,7 +286,6 @@ public class GTaskClient { e.printStackTrace(); return false; } catch (Exception e) { - // simply catch all exceptions Log.e(TAG, "httpget gtask_url failed"); return false; } @@ -280,10 +293,20 @@ public class GTaskClient { return true; } + /** + * 获取操作 ID。 + * + * @return 操作 ID + */ private int getActionId() { return mActionId++; } + /** + * 创建 HTTP POST 请求。 + * + * @return HTTP POST 请求对象 + */ private HttpPost createHttpPost() { HttpPost httpPost = new HttpPost(mPostUrl); httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8"); @@ -291,6 +314,13 @@ public class GTaskClient { return httpPost; } + /** + * 获取 HTTP 响应内容。 + * + * @param entity HTTP 响应实体 + * @return 响应内容 + * @throws IOException 如果发生 I/O 异常 + */ private String getResponseContent(HttpEntity entity) throws IOException { String contentEncoding = null; if (entity.getContentEncoding() != null) { @@ -323,6 +353,13 @@ public class GTaskClient { } } + /** + * 发送 POST 请求。 + * + * @param js JSON 对象,请求数据 + * @return 响应 JSON 对象 + * @throws NetworkFailureException 如果发生网络失败异常 + */ private JSONObject postRequest(JSONObject js) throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); @@ -336,7 +373,6 @@ public class GTaskClient { UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); httpPost.setEntity(entity); - // execute the post HttpResponse response = mHttpClient.execute(httpPost); String jsString = getResponseContent(response.getEntity()); return new JSONObject(jsString); @@ -360,20 +396,23 @@ public class GTaskClient { } } + /** + * 创建任务。 + * + * @param task 任务对象 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public void createTask(Task task) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); - // action_list actionList.put(task.getCreateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - // client_version jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - // post JSONObject jsResponse = postRequest(jsPost); JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( GTaskStringUtils.GTASK_JSON_RESULTS).get(0); @@ -386,20 +425,23 @@ public class GTaskClient { } } + /** + * 创建任务列表。 + * + * @param tasklist 任务列表对象 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public void createTaskList(TaskList tasklist) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); - // action_list actionList.put(tasklist.getCreateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - // client version jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); - // post JSONObject jsResponse = postRequest(jsPost); JSONObject jsResult = (JSONObject) jsResponse.getJSONArray( GTaskStringUtils.GTASK_JSON_RESULTS).get(0); @@ -412,15 +454,18 @@ public class GTaskClient { } } + /** + * 提交更新操作。 + * + * @throws NetworkFailureException 如果发生网络失败异常 + */ public void commitUpdate() throws NetworkFailureException { if (mUpdateArray != null) { try { JSONObject jsPost = new JSONObject(); - // action_list jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, mUpdateArray); - // client_version jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); postRequest(jsPost); @@ -433,10 +478,14 @@ public class GTaskClient { } } + /** + * 添加更新节点。 + * + * @param node 节点对象 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public void addUpdateNode(Node node) throws NetworkFailureException { if (node != null) { - // too many update items may result in an error - // set max to 10 items if (mUpdateArray != null && mUpdateArray.length() > 10) { commitUpdate(); } @@ -447,6 +496,14 @@ public class GTaskClient { } } + /** + * 移动任务。 + * + * @param task 任务对象 + * @param preParent 原父任务列表 + * @param curParent 当前父任务列表 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public void moveTask(Task task, TaskList preParent, TaskList curParent) throws NetworkFailureException { commitUpdate(); @@ -455,26 +512,21 @@ public class GTaskClient { JSONArray actionList = new JSONArray(); JSONObject action = new JSONObject(); - // action_list action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_MOVE); action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); action.put(GTaskStringUtils.GTASK_JSON_ID, task.getGid()); if (preParent == curParent && task.getPriorSibling() != null) { - // put prioring_sibing_id only if moving within the tasklist and - // it is not the first one action.put(GTaskStringUtils.GTASK_JSON_PRIOR_SIBLING_ID, task.getPriorSibling()); } action.put(GTaskStringUtils.GTASK_JSON_SOURCE_LIST, preParent.getGid()); action.put(GTaskStringUtils.GTASK_JSON_DEST_PARENT, curParent.getGid()); if (preParent != curParent) { - // put the dest_list only if moving between tasklists action.put(GTaskStringUtils.GTASK_JSON_DEST_LIST, curParent.getGid()); } actionList.put(action); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - // client_version jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); postRequest(jsPost); @@ -486,18 +538,22 @@ public class GTaskClient { } } + /** + * 删除节点。 + * + * @param node 节点对象 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public void deleteNode(Node node) throws NetworkFailureException { commitUpdate(); try { JSONObject jsPost = new JSONObject(); JSONArray actionList = new JSONArray(); - // action_list node.setDeleted(true); actionList.put(node.getUpdateAction(getActionId())); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - // client_version jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); postRequest(jsPost); @@ -509,6 +565,12 @@ public class GTaskClient { } } + /** + * 获取任务列表。 + * + * @return 任务列表 JSON 数组 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public JSONArray getTaskLists() throws NetworkFailureException { if (!mLoggedin) { Log.e(TAG, "please login first"); @@ -517,10 +579,8 @@ public class GTaskClient { try { HttpGet httpGet = new HttpGet(mGetUrl); - HttpResponse response = null; - response = mHttpClient.execute(httpGet); + HttpResponse response = mHttpClient.execute(httpGet); - // get the task list String resString = getResponseContent(response.getEntity()); String jsBegin = "_setup("; String jsEnd = ")}"; @@ -547,6 +607,13 @@ public class GTaskClient { } } + /** + * 获取指定任务列表中的任务。 + * + * @param listGid 任务列表 ID + * @return 任务 JSON 数组 + * @throws NetworkFailureException 如果发生网络失败异常 + */ public JSONArray getTaskList(String listGid) throws NetworkFailureException { commitUpdate(); try { @@ -554,7 +621,6 @@ public class GTaskClient { JSONArray actionList = new JSONArray(); JSONObject action = new JSONObject(); - // action_list action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE, GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL); action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId()); @@ -563,7 +629,6 @@ public class GTaskClient { actionList.put(action); jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList); - // client_version jsPost.put(GTaskStringUtils.GTASK_JSON_CLIENT_VERSION, mClientVersion); JSONObject jsResponse = postRequest(jsPost); @@ -575,11 +640,19 @@ public class GTaskClient { } } + /** + * 获取同步账户。 + * + * @return 账户对象 + */ public Account getSyncAccount() { return mAccount; } + /** + * 重置更新操作数组。 + */ public void resetUpdateArray() { mUpdateArray = null; } -} +} \ No newline at end of file diff --git a/src/net/micode/notes/gtask/remote/GTaskManager.java b/src/net/micode/notes/gtask/remote/GTaskManager.java index d2b4082..3f34e00 100644 --- a/src/net/micode/notes/gtask/remote/GTaskManager.java +++ b/src/net/micode/notes/gtask/remote/GTaskManager.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -49,44 +49,56 @@ import java.util.Map; public class GTaskManager { + // 日志标签,用于调试和日志记录 private static final String TAG = GTaskManager.class.getSimpleName(); + // 同步状态常量 public static final int STATE_SUCCESS = 0; - public static final int STATE_NETWORK_ERROR = 1; - public static final int STATE_INTERNAL_ERROR = 2; - public static final int STATE_SYNC_IN_PROGRESS = 3; - public static final int STATE_SYNC_CANCELLED = 4; + // 单例模式实例 private static GTaskManager mInstance = null; + // 活动上下文,用于获取认证令牌 private Activity mActivity; + // 应用上下文 private Context mContext; + // 内容解析器,用于访问内容提供者 private ContentResolver mContentResolver; + // 标志当前是否正在同步 private boolean mSyncing; + // 标志同步是否被取消 private boolean mCancelled; + // Google 任务列表的哈希映射 private HashMap mGTaskListHashMap; + // Google 任务的哈希映射 private HashMap mGTaskHashMap; + // 元数据的哈希映射 private HashMap mMetaHashMap; + // 元数据列表 private TaskList mMetaList; + // 本地删除的 ID 集合 private HashSet mLocalDeleteIdMap; + // Google ID 到本地 ID 的映射 private HashMap mGidToNid; + // 本地 ID 到 Google ID 的映射 private HashMap mNidToGid; + // 私有构造函数,用于单例模式 private GTaskManager() { mSyncing = false; mCancelled = false; @@ -99,6 +111,7 @@ public class GTaskManager { mNidToGid = new HashMap(); } + // 获取单例实例 public static synchronized GTaskManager getInstance() { if (mInstance == null) { mInstance = new GTaskManager(); @@ -106,11 +119,13 @@ public class GTaskManager { return mInstance; } + // 设置活动上下文 public synchronized void setActivityContext(Activity activity) { - // used for getting authtoken + // 用于获取认证令牌 mActivity = activity; } + // 同步任务 public int sync(Context context, GTaskASyncTask asyncTask) { if (mSyncing) { Log.d(TAG, "Sync is in progress"); @@ -120,6 +135,7 @@ public class GTaskManager { mContentResolver = mContext.getContentResolver(); mSyncing = true; mCancelled = false; + // 清空映射和集合 mGTaskListHashMap.clear(); mGTaskHashMap.clear(); mMetaHashMap.clear(); @@ -131,18 +147,18 @@ public class GTaskManager { GTaskClient client = GTaskClient.getInstance(); client.resetUpdateArray(); - // login google task + // 登录 Google 任务 if (!mCancelled) { if (!client.login(mActivity)) { throw new NetworkFailureException("login google task failed"); } } - // get the task list from google + // 初始化 Google 任务列表 asyncTask.publishProgess(mContext.getString(R.string.sync_progress_init_list)); initGTaskList(); - // do content sync work + // 同步内容 asyncTask.publishProgess(mContext.getString(R.string.sync_progress_syncing)); syncContent(); } catch (NetworkFailureException e) { @@ -156,6 +172,7 @@ public class GTaskManager { e.printStackTrace(); return STATE_INTERNAL_ERROR; } finally { + // 清空映射和集合 mGTaskListHashMap.clear(); mGTaskHashMap.clear(); mMetaHashMap.clear(); @@ -168,6 +185,7 @@ public class GTaskManager { return mCancelled ? STATE_SYNC_CANCELLED : STATE_SUCCESS; } + // 初始化 Google 任务列表 private void initGTaskList() throws NetworkFailureException { if (mCancelled) return; @@ -175,7 +193,7 @@ public class GTaskManager { try { JSONArray jsTaskLists = client.getTaskLists(); - // init meta list first + // 初始化元数据列表 mMetaList = null; for (int i = 0; i < jsTaskLists.length(); i++) { JSONObject object = jsTaskLists.getJSONObject(i); @@ -187,7 +205,7 @@ public class GTaskManager { mMetaList = new TaskList(); mMetaList.setContentByRemoteJSON(object); - // load meta data + // 加载元数据 JSONArray jsMetas = client.getTaskList(gid); for (int j = 0; j < jsMetas.length(); j++) { object = (JSONObject) jsMetas.getJSONObject(j); @@ -203,7 +221,7 @@ public class GTaskManager { } } - // create meta list if not existed + // 如果元数据列表不存在,则创建 if (mMetaList == null) { mMetaList = new TaskList(); mMetaList.setName(GTaskStringUtils.MIUI_FOLDER_PREFFIX @@ -211,7 +229,7 @@ public class GTaskManager { GTaskClient.getInstance().createTaskList(mMetaList); } - // init task list + // 初始化任务列表 for (int i = 0; i < jsTaskLists.length(); i++) { JSONObject object = jsTaskLists.getJSONObject(i); String gid = object.getString(GTaskStringUtils.GTASK_JSON_ID); @@ -219,13 +237,13 @@ public class GTaskManager { if (name.startsWith(GTaskStringUtils.MIUI_FOLDER_PREFFIX) && !name.equals(GTaskStringUtils.MIUI_FOLDER_PREFFIX - + GTaskStringUtils.FOLDER_META)) { + + GTaskStringUtils.FOLDER_META)) { TaskList tasklist = new TaskList(); tasklist.setContentByRemoteJSON(object); mGTaskListHashMap.put(gid, tasklist); mGTaskHashMap.put(gid, tasklist); - // load tasks + // 加载任务 JSONArray jsTasks = client.getTaskList(gid); for (int j = 0; j < jsTasks.length(); j++) { object = (JSONObject) jsTasks.getJSONObject(j); @@ -247,6 +265,7 @@ public class GTaskManager { } } + // 同步内容 private void syncContent() throws NetworkFailureException { int syncType; Cursor c = null; @@ -259,7 +278,7 @@ public class GTaskManager { return; } - // for local deleted note + // 同步本地删除的笔记 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(type<>? AND parent_id=?)", new String[] { @@ -286,10 +305,10 @@ public class GTaskManager { } } - // sync folder first + // 同步文件夹 syncFolder(); - // for note existing in database + // 同步数据库中存在的笔记 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(type=? AND parent_id<>?)", new String[] { @@ -306,10 +325,10 @@ public class GTaskManager { syncType = node.getSyncAction(c); } else { if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { - // local add + // 本地添加 syncType = Node.SYNC_ACTION_ADD_REMOTE; } else { - // remote delete + // 远程删除 syncType = Node.SYNC_ACTION_DEL_LOCAL; } } @@ -326,7 +345,7 @@ public class GTaskManager { } } - // go through remaining items + // 同步剩余项目 Iterator> iter = mGTaskHashMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); @@ -334,23 +353,21 @@ public class GTaskManager { doContentSync(Node.SYNC_ACTION_ADD_LOCAL, node, null); } - // mCancelled can be set by another thread, so we neet to check one by - // one - // clear local delete table + // 清除本地删除表 if (!mCancelled) { if (!DataUtils.batchDeleteNotes(mContentResolver, mLocalDeleteIdMap)) { throw new ActionFailureException("failed to batch-delete local deleted notes"); } } - // refresh local sync id + // 刷新本地同步 ID if (!mCancelled) { GTaskClient.getInstance().commitUpdate(); refreshLocalSyncId(); } - } + // 同步文件夹 private void syncFolder() throws NetworkFailureException { Cursor c = null; String gid; @@ -361,7 +378,7 @@ public class GTaskManager { return; } - // for root folder + // 同步根文件夹 try { c = mContentResolver.query(ContentUris.withAppendedId(Notes.CONTENT_NOTE_URI, Notes.ID_ROOT_FOLDER), SqlNote.PROJECTION_NOTE, null, null, null); @@ -373,7 +390,7 @@ public class GTaskManager { mGTaskHashMap.remove(gid); mGidToNid.put(gid, (long) Notes.ID_ROOT_FOLDER); mNidToGid.put((long) Notes.ID_ROOT_FOLDER, gid); - // for system folder, only update remote name if necessary + // 如果系统文件夹名称不同,则更新远程名称 if (!node.getName().equals( GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_DEFAULT)) doContentSync(Node.SYNC_ACTION_UPDATE_REMOTE, node, c); @@ -390,11 +407,11 @@ public class GTaskManager { } } - // for call-note folder + // 同步通话记录文件夹 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(_id=?)", new String[] { - String.valueOf(Notes.ID_CALL_RECORD_FOLDER) + String.valueOf(Notes.ID_CALL_RECORD_FOLDER) }, null); if (c != null) { if (c.moveToNext()) { @@ -404,8 +421,7 @@ public class GTaskManager { mGTaskHashMap.remove(gid); mGidToNid.put(gid, (long) Notes.ID_CALL_RECORD_FOLDER); mNidToGid.put((long) Notes.ID_CALL_RECORD_FOLDER, gid); - // for system folder, only update remote name if - // necessary + // 如果系统文件夹名称不同,则更新远程名称 if (!node.getName().equals( GTaskStringUtils.MIUI_FOLDER_PREFFIX + GTaskStringUtils.FOLDER_CALL_NOTE)) @@ -424,7 +440,7 @@ public class GTaskManager { } } - // for local existing folders + // 同步数据库中存在的文件夹 try { c = mContentResolver.query(Notes.CONTENT_NOTE_URI, SqlNote.PROJECTION_NOTE, "(type=? AND parent_id<>?)", new String[] { @@ -441,10 +457,10 @@ public class GTaskManager { syncType = node.getSyncAction(c); } else { if (c.getString(SqlNote.GTASK_ID_COLUMN).trim().length() == 0) { - // local add + // 本地添加 syncType = Node.SYNC_ACTION_ADD_REMOTE; } else { - // remote delete + // 远程删除 syncType = Node.SYNC_ACTION_DEL_LOCAL; } } @@ -460,7 +476,7 @@ public class GTaskManager { } } - // for remote add folders + // 同步远程添加的文件夹 Iterator> iter = mGTaskListHashMap.entrySet().iterator(); while (iter.hasNext()) { Map.Entry entry = iter.next(); @@ -476,6 +492,7 @@ public class GTaskManager { GTaskClient.getInstance().commitUpdate(); } + // 执行内容同步 private void doContentSync(int syncType, Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; @@ -510,18 +527,18 @@ public class GTaskManager { updateRemoteNode(node, c); break; case Node.SYNC_ACTION_UPDATE_CONFLICT: - // merging both modifications maybe a good idea - // right now just use local update simply + // 合并冲突修改(当前简单地使用本地更新) updateRemoteNode(node, c); break; case Node.SYNC_ACTION_NONE: break; case Node.SYNC_ACTION_ERROR: default: - throw new ActionFailureException("unkown sync action type"); + throw new ActionFailureException("unknown sync action type"); } } + // 添加本地节点 private void addLocalNode(Node node) throws NetworkFailureException { if (mCancelled) { return; @@ -549,7 +566,6 @@ public class GTaskManager { if (note.has(NoteColumns.ID)) { long id = note.getLong(NoteColumns.ID); if (DataUtils.existInNoteDatabase(mContentResolver, id)) { - // the id is not available, have to create a new one note.remove(NoteColumns.ID); } } @@ -562,8 +578,6 @@ public class GTaskManager { if (data.has(DataColumns.ID)) { long dataId = data.getLong(DataColumns.ID); if (DataUtils.existInDataDatabase(mContentResolver, dataId)) { - // the data id is not available, have to create - // a new one data.remove(DataColumns.ID); } } @@ -584,25 +598,26 @@ public class GTaskManager { sqlNote.setParentId(parentId.longValue()); } - // create the local node + // 创建本地节点 sqlNote.setGtaskId(node.getGid()); sqlNote.commit(false); - // update gid-nid mapping + // 更新 Google ID 到本地 ID 的映射 mGidToNid.put(node.getGid(), sqlNote.getId()); mNidToGid.put(sqlNote.getId(), node.getGid()); - // update meta + // 更新元数据 updateRemoteMeta(node.getGid(), sqlNote); } + // 更新本地节点 private void updateLocalNode(Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; } SqlNote sqlNote; - // update the note locally + // 更新本地节点 sqlNote = new SqlNote(mContext, c); sqlNote.setContent(node.getLocalJSONFromContent()); @@ -615,10 +630,11 @@ public class GTaskManager { sqlNote.setParentId(parentId.longValue()); sqlNote.commit(true); - // update meta info + // 更新元数据 updateRemoteMeta(node.getGid(), sqlNote); } + // 添加远程节点 private void addRemoteNode(Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; @@ -627,7 +643,7 @@ public class GTaskManager { SqlNote sqlNote = new SqlNote(mContext, c); Node n; - // update remotely + // 更新远程节点 if (sqlNote.isNoteType()) { Task task = new Task(); task.setContentByLocalJSON(sqlNote.getContent()); @@ -642,12 +658,12 @@ public class GTaskManager { GTaskClient.getInstance().createTask(task); n = (Node) task; - // add meta + // 添加元数据 updateRemoteMeta(task.getGid(), sqlNote); } else { TaskList tasklist = null; - // we need to skip folder if it has already existed + // 如果文件夹已存在,则跳过 String folderName = GTaskStringUtils.MIUI_FOLDER_PREFFIX; if (sqlNote.getId() == Notes.ID_ROOT_FOLDER) folderName += GTaskStringUtils.FOLDER_DEFAULT; @@ -671,7 +687,7 @@ public class GTaskManager { } } - // no match we can add now + // 添加新文件夹 if (tasklist == null) { tasklist = new TaskList(); tasklist.setContentByLocalJSON(sqlNote.getContent()); @@ -681,17 +697,18 @@ public class GTaskManager { n = (Node) tasklist; } - // update local note + // 更新本地节点 sqlNote.setGtaskId(n.getGid()); sqlNote.commit(false); sqlNote.resetLocalModified(); sqlNote.commit(true); - // gid-id mapping + // 更新 Google ID 到本地 ID 的映射 mGidToNid.put(n.getGid(), sqlNote.getId()); mNidToGid.put(sqlNote.getId(), n.getGid()); } + // 更新远程节点 private void updateRemoteNode(Node node, Cursor c) throws NetworkFailureException { if (mCancelled) { return; @@ -699,14 +716,14 @@ public class GTaskManager { SqlNote sqlNote = new SqlNote(mContext, c); - // update remotely + // 更新远程节点 node.setContentByLocalJSON(sqlNote.getContent()); GTaskClient.getInstance().addUpdateNode(node); - // update meta + // 更新元数据 updateRemoteMeta(node.getGid(), sqlNote); - // move task if necessary + // 移动任务(如果需要) if (sqlNote.isNoteType()) { Task task = (Task) node; TaskList preParentList = task.getParent(); @@ -725,11 +742,12 @@ public class GTaskManager { } } - // clear local modified flag + // 清除本地修改标记 sqlNote.resetLocalModified(); sqlNote.commit(true); } + // 更新远程元数据 private void updateRemoteMeta(String gid, SqlNote sqlNote) throws NetworkFailureException { if (sqlNote != null && sqlNote.isNoteType()) { MetaData metaData = mMetaHashMap.get(gid); @@ -746,12 +764,13 @@ public class GTaskManager { } } + // 刷新本地同步 ID private void refreshLocalSyncId() throws NetworkFailureException { if (mCancelled) { return; } - // get the latest gtask list + // 获取最新的 Google 任务列表 mGTaskHashMap.clear(); mGTaskListHashMap.clear(); mMetaHashMap.clear(); @@ -790,11 +809,13 @@ public class GTaskManager { } } + // 获取同步账户 public String getSyncAccount() { return GTaskClient.getInstance().getSyncAccount().name; } + // 取消同步 public void cancelSync() { mCancelled = true; } -} +} \ No newline at end of file diff --git a/src/net/micode/notes/gtask/remote/GTaskSyncService.java b/src/net/micode/notes/gtask/remote/GTaskSyncService.java index cca36f7..394d552 100644 --- a/src/net/micode/notes/gtask/remote/GTaskSyncService.java +++ b/src/net/micode/notes/gtask/remote/GTaskSyncService.java @@ -5,7 +5,7 @@ * 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 + * 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, @@ -24,105 +24,123 @@ import android.os.Bundle; import android.os.IBinder; public class GTaskSyncService extends Service { - public final static String ACTION_STRING_NAME = "sync_action_type"; - - public final static int ACTION_START_SYNC = 0; - - public final static int ACTION_CANCEL_SYNC = 1; - - public final static int ACTION_INVALID = 2; - + // 广播 Action 名称,用于标识同步服务的广播 public final static String GTASK_SERVICE_BROADCAST_NAME = "net.micode.notes.gtask.remote.gtask_sync_service"; + // 广播额外数据键,用于标识是否正在同步 public final static String GTASK_SERVICE_BROADCAST_IS_SYNCING = "isSyncing"; + // 广播额外数据键,用于同步进度消息 public final static String GTASK_SERVICE_BROADCAST_PROGRESS_MSG = "progressMsg"; + // 操作类型常量 + public final static int ACTION_START_SYNC = 0; // 开始同步 + public final static int ACTION_CANCEL_SYNC = 1; // 取消同步 + public final static int ACTION_INVALID = 2; // 无效操作 + + // 操作类型键,用于 Intent 额外数据 + public final static String ACTION_STRING_NAME = "sync_action_type"; + + // 同步任务实例 private static GTaskASyncTask mSyncTask = null; + // 同步进度消息 private static String mSyncProgress = ""; + // 开始同步操作 private void startSync() { if (mSyncTask == null) { + // 创建并启动同步任务 mSyncTask = new GTaskASyncTask(this, new GTaskASyncTask.OnCompleteListener() { public void onComplete() { - mSyncTask = null; - sendBroadcast(""); - stopSelf(); + mSyncTask = null; // 同步完成,清空任务引用 + sendBroadcast(""); // 发送广播通知同步完成 + stopSelf(); // 停止服务 } }); - sendBroadcast(""); - mSyncTask.execute(); + sendBroadcast(""); // 发送广播通知同步开始 + mSyncTask.execute(); // 执行同步任务 } } + // 取消同步操作 private void cancelSync() { if (mSyncTask != null) { - mSyncTask.cancelSync(); + mSyncTask.cancelSync(); // 取消同步任务 } } + // 服务创建时调用 @Override public void onCreate() { - mSyncTask = null; + mSyncTask = null; // 初始化同步任务为 null } + // 服务启动时调用 @Override public int onStartCommand(Intent intent, int flags, int startId) { Bundle bundle = intent.getExtras(); if (bundle != null && bundle.containsKey(ACTION_STRING_NAME)) { + // 根据操作类型执行相应操作 switch (bundle.getInt(ACTION_STRING_NAME, ACTION_INVALID)) { case ACTION_START_SYNC: - startSync(); + startSync(); // 开始同步 break; case ACTION_CANCEL_SYNC: - cancelSync(); + cancelSync(); // 取消同步 break; default: break; } - return START_STICKY; + return START_STICKY; // 返回 sticky 模式,确保服务被系统杀死后重新创建 } return super.onStartCommand(intent, flags, startId); } + // 内存不足时调用 @Override public void onLowMemory() { if (mSyncTask != null) { - mSyncTask.cancelSync(); + mSyncTask.cancelSync(); // 取消同步任务 } } + // 绑定服务时调用 public IBinder onBind(Intent intent) { - return null; + return null; // 返回 null,表示不支持绑定 } + // 发送广播通知 public void sendBroadcast(String msg) { - mSyncProgress = msg; + mSyncProgress = msg; // 更新同步进度消息 Intent intent = new Intent(GTASK_SERVICE_BROADCAST_NAME); - intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); - intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); - sendBroadcast(intent); + intent.putExtra(GTASK_SERVICE_BROADCAST_IS_SYNCING, mSyncTask != null); // 添加是否正在同步的额外数据 + intent.putExtra(GTASK_SERVICE_BROADCAST_PROGRESS_MSG, msg); // 添加同步进度消息的额外数据 + sendBroadcast(intent); // 发送广播 } + // 静态方法,启动同步服务 public static void startSync(Activity activity) { - GTaskManager.getInstance().setActivityContext(activity); - Intent intent = new Intent(activity, GTaskSyncService.class); - intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC); - activity.startService(intent); + GTaskManager.getInstance().setActivityContext(activity); // 设置活动上下文 + Intent intent = new Intent(activity, GTaskSyncService.class); // 创建 Intent + intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_START_SYNC); // 添加操作类型额外数据 + activity.startService(intent); // 启动服务 } + // 静态方法,取消同步服务 public static void cancelSync(Context context) { - Intent intent = new Intent(context, GTaskSyncService.class); - intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC); - context.startService(intent); + Intent intent = new Intent(context, GTaskSyncService.class); // 创建 Intent + intent.putExtra(GTaskSyncService.ACTION_STRING_NAME, GTaskSyncService.ACTION_CANCEL_SYNC); // 添加操作类型额外数据 + context.startService(intent); // 启动服务 } + // 静态方法,检查是否正在同步 public static boolean isSyncing() { - return mSyncTask != null; + return mSyncTask != null; // 返回同步任务是否为 null } + // 静态方法,获取同步进度消息 public static String getProgressString() { - return mSyncProgress; + return mSyncProgress; // 返回同步进度消息 } -} +} \ No newline at end of file diff --git a/src/新建 文本文档.txt b/src/新建 文本文档.txt new file mode 100644 index 0000000..56a6051 --- /dev/null +++ b/src/新建 文本文档.txt @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/test1.txt b/test1.txt index 0ea5d48..105f105 100644 --- a/test1.txt +++ b/test1.txt @@ -1 +1,3 @@ -111222333 \ No newline at end of file +111222333 +8858585 +33333 \ No newline at end of file