代码分析

master
ptka4xvyr 2 years ago
parent d750e84abd
commit 3494c9de3d

@ -29,8 +29,17 @@ import net.micode.notes.ui.NotesListActivity;
import net.micode.notes.ui.NotesPreferenceActivity;
/*GTask
*
* private void showNotification(int tickerId, String content)
* protected Integer doInBackground(Void... unused) 线
* protected void onProgressUpdate(String... progress) 使 线
* protected void onPostExecute(Integer result) Handler UI使doInBackground UI
*/
public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
private static int GTASK_SYNC_NOTIFICATION_ID = 5234235;
public interface OnCompleteListener {
@ -57,57 +66,52 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
mTaskManager.cancelSync();
}
public void publishProgess(String message) {
public void publishProgess(String message) { // 发布进度单位系统将会调用onProgressUpdate()方法更新这些值
publishProgress(new String[] {
message
message
});
}
private void showNotification(int tickerId, String content) {
PendingIntent pendingIntent;
Notification notification = new Notification(R.drawable.notification, mContext
.getString(tickerId), System.currentTimeMillis());
notification.defaults = Notification.DEFAULT_LIGHTS; // 调用系统自带灯光
notification.flags = Notification.FLAG_AUTO_CANCEL; // 点击清除按钮或点击通知后会自动消失
PendingIntent pendingIntent; //一个描述了想要启动一个Activity、Broadcast或是Service的意图
if (tickerId != R.string.ticker_success) {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesPreferenceActivity.class), 0);
NotesPreferenceActivity.class), 0); //如果同步不成功那么从系统取得一个用于启动一个NotesPreferenceActivity的PendingIntent对象
} else {
pendingIntent = PendingIntent.getActivity(mContext, 0, new Intent(mContext,
NotesListActivity.class), 0);
NotesListActivity.class), 0); //如果同步成功那么从系统取得一个用于启动一个NotesListActivity的PendingIntent对象
}
Notification.Builder builder = new Notification.Builder(mContext)
.setAutoCancel(true)
.setContentTitle(mContext.getString(R.string.app_name))
.setContentText(content)
.setContentIntent(pendingIntent)
.setWhen(System.currentTimeMillis())
.setOngoing(true);
Notification notification=builder.getNotification();
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);
//notification.setLatestEventInfo(mContext, mContext.getString(R.string.app_name), content,
// pendingIntent);
mNotifiManager.notify(GTASK_SYNC_NOTIFICATION_ID, notification);//通过NotificationManager对象的notify方法来执行一个notification的消息
}
@Override
protected Integer doInBackground(Void... unused) {
publishProgess(mContext.getString(R.string.sync_progress_login, NotesPreferenceActivity
.getSyncAccountName(mContext)));
return mTaskManager.sync(mContext, this);
.getSyncAccountName(mContext))); //利用getString,将把 NotesPreferenceActivity.getSyncAccountName(mContext))的字符串内容传进sync_progress_login中
return mTaskManager.sync(mContext, this); //进行后台同步具体操作
}
@Override
protected void onProgressUpdate(String... progress) {
showNotification(R.string.ticker_syncing, progress[0]);
if (mContext instanceof GTaskSyncService) {
if (mContext instanceof GTaskSyncService) { //instanceof 判断mContext是否是GTaskSyncService的实例
((GTaskSyncService) mContext).sendBroadcast(progress[0]);
}
}
@Override
protected void onPostExecute(Integer result) {
protected void onPostExecute(Integer result) { //用于在执行完后台任务后更新UI,显示结果
if (result == GTaskManager.STATE_SUCCESS) {
showNotification(R.string.ticker_success, mContext.getString(
R.string.success_sync_account, mTaskManager.getSyncAccount()));
NotesPreferenceActivity.setLastSyncTime(mContext, System.currentTimeMillis());
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) {
@ -115,11 +119,11 @@ public class GTaskASyncTask extends AsyncTask<Void, String, Integer> {
} 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() {
new Thread(new Runnable() { //这里好像是方法内的一个线程,但是并不太懂什么意思
public void run() {
public void run() { //完成后的操作使用onComplete()将所有值都重新初始化,相当于完成一次操作
mOnCompleteListener.onComplete();
}
}).start();

@ -61,10 +61,15 @@ import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/*
* GTASKGTASK
* 使accountManager JSONObject HttpParams authToken Gid
*/
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_URL = "https://mail.google.com/tasks/"; //这个是指定的URL
private static final String GTASK_GET_URL = "https://mail.google.com/tasks/ig";
@ -102,6 +107,10 @@ public class GTaskClient {
mUpdateArray = null;
}
/*
* 使 getInstance()
* mInstance
*/
public static synchronized GTaskClient getInstance() {
if (mInstance == null) {
mInstance = new GTaskClient();
@ -109,42 +118,50 @@ public class GTaskClient {
return mInstance;
}
/*Activity
*
* 使URL使URL
* truefalse
*/
public boolean login(Activity activity) {
// we suppose that the cookie would expire after 5 minutes
// then we need to re-login
//判断距离最后一次登录操作是否超过5分钟
final long interval = 1000 * 60 * 5;
if (mLastLoginTime + interval < System.currentTimeMillis()) {
mLoggedin = false;
}
// need to re-login after account switch
// need to re-login after account switch 重新登录操作
if (mLoggedin
&& !TextUtils.equals(getSyncAccount().name, NotesPreferenceActivity
.getSyncAccountName(activity))) {
mLoggedin = false;
}
//如果没超过时间,则不需要重新登录
if (mLoggedin) {
Log.d(TAG, "already logged in");
return true;
}
mLastLoginTime = System.currentTimeMillis();
String authToken = loginGoogleAccount(activity, false);
mLastLoginTime = System.currentTimeMillis();//更新最后登录时间,改为系统当前的时间
String authToken = loginGoogleAccount(activity, false);//判断是否登录到谷歌账户
if (authToken == null) {
Log.e(TAG, "login google account failed");
return false;
}
// login with custom domain if necessary
if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase()
//尝试使用用户自己的域名登录
if (!(mAccount.name.toLowerCase().endsWith("gmail.com") || mAccount.name.toLowerCase() //将用户账号名改为统一格式(小写)后判断是否为一个谷歌账号地址
.endsWith("googlemail.com"))) {
StringBuilder url = new StringBuilder(GTASK_URL).append("a/");
int index = mAccount.name.indexOf('@') + 1;
String suffix = mAccount.name.substring(index);
url.append(suffix + "/");
mGetUrl = url.toString() + "ig";
mPostUrl = url.toString() + "r/ig";
mGetUrl = url.toString() + "ig"; //设置用户对应的getUrl
mPostUrl = url.toString() + "r/ig"; //设置用户对应的postUrl
if (tryToLoginGtask(activity, authToken)) {
mLoggedin = true;
@ -152,6 +169,7 @@ public class GTaskClient {
}
// try to login with google official url
//如果用户账户无法登录则使用谷歌官方的URI进行登录
if (!mLoggedin) {
mGetUrl = GTASK_GET_URL;
mPostUrl = GTASK_POST_URL;
@ -164,10 +182,15 @@ public class GTaskClient {
return true;
}
/*
* 使
* 使AccountManager
*
*/
private String loginGoogleAccount(Activity activity, boolean invalidateToken) {
String authToken;
AccountManager accountManager = AccountManager.get(activity);
Account[] accounts = accountManager.getAccountsByType("com.google");
String authToken; //令牌,是登录操作保证安全性的一个方法
AccountManager accountManager = AccountManager.get(activity);//AccountManager这个类给用户提供了集中注册账号的接口
Account[] accounts = accountManager.getAccountsByType("com.google");//获取全部以com.google结尾的account
if (accounts.length == 0) {
Log.e(TAG, "there is no available google account");
@ -176,6 +199,7 @@ public class GTaskClient {
String accountName = NotesPreferenceActivity.getSyncAccountName(activity);
Account account = null;
//遍历获得的accounts信息寻找已经记录过的账户信息
for (Account a : accounts) {
if (a.name.equals(accountName)) {
account = a;
@ -190,11 +214,13 @@ public class GTaskClient {
}
// get the token now
//获取选中账号的令牌
AccountManagerFuture<Bundle> accountManagerFuture = accountManager.getAuthToken(account,
"goanna_mobile", null, activity, null, null);
try {
Bundle authTokenBundle = accountManagerFuture.getResult();
authToken = authTokenBundle.getString(AccountManager.KEY_AUTHTOKEN);
//如果是invalidateToken那么需要调用invalidateAuthToken(String, String)方法废除这个无效token
if (invalidateToken) {
accountManager.invalidateAuthToken("com.google", authToken);
loginGoogleAccount(activity, false);
@ -207,10 +233,12 @@ public class GTaskClient {
return authToken;
}
//尝试登陆Gtask这只是一个预先判断令牌是否是有效以及是否能登上GTask的方法,而不是具体实现登陆的方法
private boolean tryToLoginGtask(Activity activity, String authToken) {
if (!loginGtask(authToken)) {
// maybe the auth token is out of date, now let's invalidate the
// maybe the auth token is out of authTokedate, now let's invalidate the
// token and try again
//删除过一个无效的authToken申请一个新的后再次尝试登陆
authToken = loginGoogleAccount(activity, true);
if (authToken == null) {
Log.e(TAG, "login google account failed");
@ -225,25 +253,27 @@ public class GTaskClient {
return true;
}
//实现登录GTask的具体操作
private boolean loginGtask(String authToken) {
int timeoutConnection = 10000;
int timeoutSocket = 15000;
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
int timeoutSocket = 15000; //socket是一种通信连接实现数据的交换的端口
HttpParams httpParameters = new BasicHttpParams(); //实例化一个新的HTTP参数类
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);//设置连接超时时间
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);//设置设置端口超时时间
mHttpClient = new DefaultHttpClient(httpParameters);
BasicCookieStore localBasicCookieStore = new BasicCookieStore();
BasicCookieStore localBasicCookieStore = new BasicCookieStore(); //设置本地cookie
mHttpClient.setCookieStore(localBasicCookieStore);
HttpProtocolParams.setUseExpectContinue(mHttpClient.getParams(), false);
// login gtask
try {
String loginUrl = mGetUrl + "?auth=" + authToken;
HttpGet httpGet = new HttpGet(loginUrl);
String loginUrl = mGetUrl + "?auth=" + authToken; //设置登录的url
HttpGet httpGet = new HttpGet(loginUrl); //通过登录的uri实例化网页上资源的查找
HttpResponse response = null;
response = mHttpClient.execute(httpGet);
// get the cookie now
//获取CookieStore里存放的cookie,看如果存有“GTL(不知道什么意思)”则说明有验证成功的有效的cookie
List<Cookie> cookies = mHttpClient.getCookieStore().getCookies();
boolean hasAuthCookie = false;
for (Cookie cookie : cookies) {
@ -256,6 +286,7 @@ public class GTaskClient {
}
// get the client version
//获取client的内容具体操作是在返回的Content中截取从_setup(开始到)}</script>中间的字符串内容也就是gtask_url的内容
String resString = getResponseContent(response.getEntity());
String jsBegin = "_setup(";
String jsEnd = ")}</script>";
@ -284,6 +315,10 @@ public class GTaskClient {
return mActionId++;
}
/*
* 使HttpPost
* httpPost
*/
private HttpPost createHttpPost() {
HttpPost httpPost = new HttpPost(mPostUrl);
httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
@ -291,24 +326,28 @@ public class GTaskClient {
return httpPost;
}
/*URL
* 使getContentEncoding()
*
*/
private String getResponseContent(HttpEntity entity) throws IOException {
String contentEncoding = null;
if (entity.getContentEncoding() != null) {
if (entity.getContentEncoding() != null) {//通过URL得到HttpEntity对象如果不为空则使用getContent方法创建一个流将数据从网络都过来
contentEncoding = entity.getContentEncoding().getValue();
Log.d(TAG, "encoding: " + contentEncoding);
}
InputStream input = entity.getContent();
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {
if (contentEncoding != null && contentEncoding.equalsIgnoreCase("gzip")) {//GZIP是使用DEFLATE进行压缩数据的另一个压缩库
input = new GZIPInputStream(entity.getContent());
} else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) {
} else if (contentEncoding != null && contentEncoding.equalsIgnoreCase("deflate")) {//DEFLATE是一个无专利的压缩算法它可以实现无损数据压缩
Inflater inflater = new Inflater(true);
input = new InflaterInputStream(entity.getContent(), inflater);
}
try {
InputStreamReader isr = new InputStreamReader(input);
BufferedReader br = new BufferedReader(isr);
BufferedReader br = new BufferedReader(isr);//是一个包装类,它可以包装字符流,将字符流放入缓存里,先把字符读到缓存里,到缓存满了时候,再读入内存,是为了提供读的效率而设计的
StringBuilder sb = new StringBuilder();
while (true) {
@ -323,20 +362,28 @@ public class GTaskClient {
}
}
/*JSON
* jsonjs
* UrlEncodedFormEntity entityhttpPost.setEntity(entity)jshttpPost
* 使getResponseContent
* json
*/
private JSONObject postRequest(JSONObject js) throws NetworkFailureException {
if (!mLoggedin) {
if (!mLoggedin) {//未登录
Log.e(TAG, "please login first");
throw new ActionFailureException("not logged in");
}
//实例化一个httpPost的对象用来向服务器传输数据在这里就是发送请求而请求的内容在js里
HttpPost httpPost = createHttpPost();
try {
LinkedList<BasicNameValuePair> list = new LinkedList<BasicNameValuePair>();
list.add(new BasicNameValuePair("r", js.toString()));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8");
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, "UTF-8"); //UrlEncodedFormEntity()的形式比较单一,是普通的键值对
httpPost.setEntity(entity);
// execute the post
//执行这个请求
HttpResponse response = mHttpClient.execute(httpPost);
String jsString = getResponseContent(response.getEntity());
return new JSONObject(jsString);
@ -360,6 +407,12 @@ public class GTaskClient {
}
}
/*
* .gtask.data.TaskTask
* jsonTask,jsPost
* postRequest
* 使task.setGidtasknew_ID
*/
public void createTask(Task task) throws NetworkFailureException {
commitUpdate();
try {
@ -386,6 +439,9 @@ public class GTaskClient {
}
}
/*
* createTasktasklistgid
*/
public void createTaskList(TaskList tasklist) throws NetworkFailureException {
commitUpdate();
try {
@ -412,6 +468,11 @@ public class GTaskClient {
}
}
/*
*
* 使JSONObject使jsPost.putPutUpdateArrayClientVersion
* 使postRequestjspost,
*/
public void commitUpdate() throws NetworkFailureException {
if (mUpdateArray != null) {
try {
@ -433,6 +494,10 @@ public class GTaskClient {
}
}
/*
*
* commitUpdate()
*/
public void addUpdateNode(Node node) throws NetworkFailureException {
if (node != null) {
// too many update items may result in an error
@ -447,6 +512,12 @@ public class GTaskClient {
}
}
/*
* task,tasktask
* getGidtaskgid
* JSONObject.put(String name, Object value)task
* postRequest
*/
public void moveTask(Task task, TaskList preParent, TaskList curParent)
throws NetworkFailureException {
commitUpdate();
@ -463,15 +534,17 @@ public class GTaskClient {
if (preParent == curParent && task.getPriorSibling() != null) {
// put prioring_sibing_id only if moving within the tasklist and
// it is not the first one
//设置优先级ID只有当移动是发生在文件中
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());
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);
//最后将ACTION_LIST加入到jsPost中
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
@ -486,6 +559,11 @@ public class GTaskClient {
}
}
/*
*
* JSON
* 使postRequest
*/
public void deleteNode(Node node) throws NetworkFailureException {
commitUpdate();
try {
@ -494,7 +572,7 @@ public class GTaskClient {
// action_list
node.setDeleted(true);
actionList.put(node.getUpdateAction(getActionId()));
actionList.put(node.getUpdateAction(getActionId())); //这里会获取到删除操作的ID加入到actionLiast中
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
// client_version
@ -509,6 +587,11 @@ public class GTaskClient {
}
}
/*
*
* GetURI使getResponseContent
* "_setup(")}</script>GTASK_JSON_LISTS
*/
public JSONArray getTaskLists() throws NetworkFailureException {
if (!mLoggedin) {
Log.e(TAG, "please login first");
@ -521,6 +604,7 @@ public class GTaskClient {
response = mHttpClient.execute(httpGet);
// get the task list
//筛选工作把筛选出的字符串放入jsString
String resString = getResponseContent(response.getEntity());
String jsBegin = "_setup(";
String jsEnd = ")}</script>";
@ -531,6 +615,7 @@ public class GTaskClient {
jsString = resString.substring(begin + jsBegin.length(), end);
}
JSONObject js = new JSONObject(jsString);
//获取GTASK_JSON_LISTS
return js.getJSONObject("t").getJSONArray(GTaskStringUtils.GTASK_JSON_LISTS);
} catch (ClientProtocolException e) {
Log.e(TAG, e.toString());
@ -547,6 +632,9 @@ public class GTaskClient {
}
}
/*
* TASKListgid,
*/
public JSONArray getTaskList(String listGid) throws NetworkFailureException {
commitUpdate();
try {
@ -558,7 +646,7 @@ public class GTaskClient {
action.put(GTaskStringUtils.GTASK_JSON_ACTION_TYPE,
GTaskStringUtils.GTASK_JSON_ACTION_TYPE_GETALL);
action.put(GTaskStringUtils.GTASK_JSON_ACTION_ID, getActionId());
action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid);
action.put(GTaskStringUtils.GTASK_JSON_LIST_ID, listGid); //这里设置为传入的listGid
action.put(GTaskStringUtils.GTASK_JSON_GET_DELETED, false);
actionList.put(action);
jsPost.put(GTaskStringUtils.GTASK_JSON_ACTION_LIST, actionList);
@ -579,6 +667,7 @@ public class GTaskClient {
return mAccount;
}
//重置更新的内容
public void resetUpdateArray() {
mUpdateArray = null;
}

Loading…
Cancel
Save