来说说实现发布微博功能的关键点:
1. 任务队列(多线程的实现)
2. 任务存储
3. 任务监视
4. 任务处理
发布微博我们点击发送按钮就会调用send()方法,来看看send方法里面做了什么操作
// 发送
private void send() {
String text = weiboContent.getText().toString();
switch (type) {
case TYPE_POST_WEIBO: // 发送微博
if (filename != null && “”.equals(“”)) {
text = “分享图片”;
} else if (“”.equals(text)) {
Toast.makeText(this, “请输入微博内容”, Toast.LENGTH_LONG).show();
return;
}
// 创建一个发布微博的任务
PostWeiboTask postWeiboTask = new PostWeiboTask();
postWeiboTask.text = text;
postWeiboTask.file = filename;
Tools.getGlobalObject(this).getWorkQueueStorage()
.addTask(postWeiboTask);
Toast.makeText(this, “已经提交发布微博任务到工作队列”, Toast.LENGTH_LONG).show();
break;
case TYPE_FORWARD: // 转发微博
if (“”.equals(text)) {
Toast.makeText(this, “请输入微博内容”, Toast.LENGTH_LONG).show();
return;
}
RepostWeiboTask repostWeiboTask = new RepostWeiboTask();
repostWeiboTask.id = statusId;
repostWeiboTask.text = text;
if (isCommentCheckBox.isChecked()) { // 是否评论
repostWeiboTask.isComment = 1;
} else {
repostWeiboTask.isComment = 0;
}
Tools.getGlobalObject(this).getWorkQueueStorage()
.addTask(repostWeiboTask);
Toast.makeText(this, “已经提交转发微博任务到工作队列”, Toast.LENGTH_LONG).show();
break;
case TYPE_COMMENT:
if (“”.equals(text)) {
Toast.makeText(this, “请输入微博内容”, Toast.LENGTH_LONG).show();
return;
}
CommentWeiboTask commentWeiboTask = new CommentWeiboTask();
commentWeiboTask.text = text;
commentWeiboTask.weiboText = text + this.text;
commentWeiboTask.id = statusId;
if (postWeiboCheckBox.isChecked()) {
commentWeiboTask.postWeibo = true;
} else {
commentWeiboTask.postWeibo = false;
}
Tools.getGlobalObject(this).getWorkQueueStorage()
.addTask(commentWeiboTask);
// 返回结果
setResult(TYPE_COMMENT);
Toast.makeText(this, “已经提交评论微博任务到工作队列”, Toast.LENGTH_LONG);
break;
}
finish();
}
这里只看发送微博就行了,至于转发微博还有评论都是提交到任务队列里去的,都是类似的实现过程,所以我介绍完发布微博这个流程,关于转发和评论的实现我就不多介绍,只会在需要注意的地方介绍一下。
我们可以看到,会先创建一个任务,然后把任务添加到任务队列里面
PostWeiboTask这个类,里面的内容如下:
package com.wwj.sina.weibo.workqueue.task;
/**
-
发布微博任务
-
@author wwj
*/
public class PostWeiboTask extends ParentTask {
public String text;
public String file;
}
它继承ParentTask这个类
package com.wwj.sina.weibo.workqueue.task;
import com.wwj.sina.weibo.workqueue.DoneAndProcess;
public class ParentTask {
public DoneAndProcess doneAndProcess;
}
而ParentTask有DoneAndProcess这个接口属性
package com.wwj.sina.weibo.workqueue;
import com.wwj.sina.weibo.workqueue.task.ParentTask;
/**
-
完成任务后的接口
-
@author wwj
*/
public interface DoneAndProcess {
void doneProcess(ParentTask task);
}
这个接口定义了一个doneProcess这个方法,里面传入一个ParentTask对象,用于完成任务后的收尾工作,这里是用来刷新数据。
与之对应的执行任务的接口DoingAndProcess
package com.wwj.sina.weibo.workqueue;
import java.util.List;
/**
-
处理任务的接口
-
@author wwj
*/
public interface DoingAndProcess {
void doingProcess(List list) throws Exception;
}
这个接口有一个方法是doingProcess,传入List为参数,意味着它要执行List里面的任务,实现这个接口的类就是用要实现各种任务的,实现这个接口的类叫TaskMan。
package com.wwj.sina.weibo.workqueue.task;
import java.util.List;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.widget.Toast;
import com.wwj.sina.weibo.net.PullFile;
import com.wwj.sina.weibo.workqueue.DoingAndProcess;
import com.wwj.sina.weibo.workqueue.task.process.CommentWeiboProcess;
import com.wwj.sina.weibo.workqueue.task.process.FavoriteWeiboProcess;
import com.wwj.sina.weibo.workqueue.task.process.PostWeiboProcess;
import com.wwj.sina.weibo.workqueue.task.process.RepostWeiboProcess;
/**
-
处理任务的中枢
-
@author wwj
*/
public class TaskMan implements DoingAndProcess {
private Activity activity;
private PostWeiboProcess postWeiboProcess;
private RepostWeiboProcess repostWeiboProcess;
private CommentWeiboProcess commentWeiboProcess;
private FavoriteWeiboProcess favoriteWeiboProcess;
private Handler msgHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
String str = String.valueOf(msg.obj);
Toast.makeText(activity, str, Toast.LENGTH_LONG).show();
super.handleMessage(msg);
};
};
public TaskMan(Activity activity) {
super();
this.activity = activity;
// 创建各种任务处理类对象
postWeiboProcess = new PostWeiboProcess(activity);
repostWeiboProcess = new RepostWeiboProcess(activity);
commentWeiboProcess = new CommentWeiboProcess(activity);
favoriteWeiboProcess = new FavoriteWeiboProcess(activity);
}
@Override
public void doingProcess(List list) throws Exception {
// 开始处理各种任务
for (Object task : list) {
// 处理发布微博任务
if (task instanceof PostWeiboTask) {
try {
postWeiboProcess.process((PostWeiboTask) task);
Message msg = new Message();
msg.obj = “成功发布微博”;
msgHandler.sendMessage(msg);
} catch (Exception e) {
exceptionProcess(task);
throw e;
}
// 处理下载文件任务
} else if (task instanceof PullFileTask) {
PullFileTask pullFileTask = (PullFileTask) task;
PullFile pullFile = new PullFile();
pullFile.doingProcess(pullFileTask.fileUrl);
// 处理转发微博任务
} else if (task instanceof RepostWeiboTask) {
try {
repostWeiboProcess.process((RepostWeiboTask) task);
Message msg = new Message();
msg.obj = “成功转发微博”;
msgHandler.sendMessage(msg);
} catch (Exception e) {
exceptionProcess(task);
throw e;
}
// 处理评论微博任务
} else if (task instanceof CommentWeiboTask) {
try {
commentWeiboProcess.process((CommentWeiboTask) task);
Message msg = new Message();
msg.obj = “成功评论微博”;
msgHandler.sendMessage(msg);
} catch (Exception e) {
exceptionProcess(task);
throw e;
}
// 处理收藏微博任务
} else if (task instanceof FavoriteWeiboTask) {
try {
favoriteWeiboProcess.process((FavoriteWeiboTask) task);
} catch (Exception e) {
exceptionProcess(task);
throw e;
}
}
}
}
// 执行任务类失败时调用该方法
private void exceptionProcess(Object task) {
Message msg = new Message();
// 任务处理
if (task instanceof PostWeiboTask) {
msg.obj = “微博发布失败”;
} else if (task instanceof RepostWeiboTask) {
msg.obj = “转发微博失败”;
} else if (task instanceof CommentWeiboTask) {
msg.obj = “评论微博失败”;
} else if (task instanceof FavoriteWeiboTask) {
msg.obj = “收藏微博失败”;
}
msgHandler.sendMessage(msg);
}
}
这个类很重要哈,我们可以看到任务队列里面的任务都在这里完成了,具体实现任务处理的类,这里只介绍PostWeiboProcess。
package com.wwj.sina.weibo.workqueue.task.process;
import com.wwj.sina.weibo.library.WeiboManager;
import com.wwj.sina.weibo.util.Tools;
import com.wwj.sina.weibo.workqueue.task.PostWeiboTask;
import android.app.Activity;
/**
-
发博微博任务处理类
-
@author wwj
*/
public class PostWeiboProcess {
private Activity activity;
public PostWeiboProcess(Activity activity) {
super();
this.activity = activity;
}
// 提交微博
public void process(PostWeiboTask task) throws Exception {
// 发布微博
WeiboManager.update(activity, Tools.getWeibo(activity), task.text, task.file);
}
}
这个就是发布微博的处理类,它有一个process方法,把发布微博的任务对象传入,这里的task就是在send()方面里面传入的,然后通过WeiboManager方法调用update的方法实现发布微博。
关于任务队列这一块是实现新浪微博最核心的,稍微有点复杂,下面我帮大家整理一下思路:
任务存储类:/xiaowu_twitter/src/com/wwj/sina/weibo/workqueue/WorkQueueStorage.java
这个类呢就是用来存储任务的,获取当前需要执行的任务,也用来移除执行完的任务列表,安装先进先出的方式实现任务按顺序执行,所以每次获取的任务就是放在最前面的,因为List的排列是顺序的。
package com.wwj.sina.weibo.workqueue;
import java.util.ArrayList;
import java.util.List;
/**
-
任务存储
-
@author wwj
*/
public class WorkQueueStorage {
// 存储文件下载任务的List
private List webFileDoingList = new ArrayList();
// 存储通用任务的List, 所有任务都必须是ParentTask的子类
private List taskList = new ArrayList();
// 获取文件下载任务(要下载的URL)
public List getDoingWebFileUrls() {
// 进行同步
synchronized (webFileDoingList) {
if (webFileDoingList.size() > 0) {
List resultList = new ArrayList();
resultList.addAll(webFileDoingList);
return resultList;
} else {
return null;
}
}
}
// 删除文件下载队列中的任务
public void removeDoingWebFileUrl(List list) {
synchronized (webFileDoingList) {
if (list != null)
webFileDoingList.removeAll(list);
}
}
// 想文件下载队列添加任务(一个Url)
public void addDoingWebFileUrl(String url) {
synchronized (webFileDoingList) {
webFileDoingList.add(url);
}
}
// 目前必须只得到到一个任务,如果一下得到多个任务,需要修改WorkQueueMonitor类的代码
// 获取一个通用任务
public List getDoingTasks() {
synchronized (taskList) {
List result = new ArrayList();
if (taskList.size() > 0) {
result.add(taskList.get(0));
return result;
} else {
return null;
}
}
}
// 删除通用任务
public void removeTask(List tasks) {
synchronized (taskList) {
if (taskList.size() > 0) {
taskList.removeAll(tasks);
}
}
}
// 添加通用任务
public void addTask(Object task) {
synchronized (taskList) {
taskList.add(task);
}
}
}
我们通过调用addTask方法,把任务添加到任务列表当中,这个方法是线程同步的。
任务监视类:/xiaowu_twitter/src/com/wwj/sina/weibo/workqueue/WorkQueueMonitor.java
package com.wwj.sina.weibo.workqueue;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.util.LogUtils;
import com.wwj.sina.weibo.workqueue.task.ParentTask;
/**
-
任务监视
-
@author Lining 说明:除了任务存储外,还需要通过线程不断扫描保存的任务的List,一旦发现任务,立刻处理。
-
这个工作交给WorkQueueMonitor类来完成
*/
public class WorkQueueMonitor implements Runnable, Const {
private WorkQueueStorage storage; // 任务存储
private Map<Integer, DoneAndProcess> doneAndProcessMap = new HashMap<Integer, DoneAndProcess>();
private DoingAndProcess doingAndProcess; // 处理任务接口对象
private Activity activity;
private boolean stopFlag = false; // 停止标识
private Thread thread; // 线程引用
private int monitorType = MONITOR_TYPE_IMAGE; // 监视类型,默认为图片
// 任务完成后,处理剩余的工作,主要是执行doneAndProcess方法
private Handler handler = new Handler() {
public void handleMessage(android.os.Message msg) {
ParentTask parentTask = (ParentTask) msg.obj;
// 如果任务本身有doneAndProcess方法,则执行此方法
if (parentTask != null && parentTask.doneAndProcess != null) {
parentTask.doneAndProcess.doneProcess(parentTask);
} else { // 否则由构造方法传入的doneAndProcess
Collection doneAndProcesses = doneAndProcessMap
.values();
for (DoneAndProcess doneAndProcess : doneAndProcesses) {
doneAndProcess.doneProcess(parentTask);
}
}
};
};
/**
-
构造函数
-
@param activity
-
窗口
-
@param storage
-
任务存储对象
-
@param doingAndProcess
-
正在处理的任务接口对象
-
@param monitorType
-
监视类型
*/
public WorkQueueMonitor(Activity activity, WorkQueueStorage storage,
DoingAndProcess doingAndProcess, int monitorType) {
super();
this.activity = activity;
this.storage = storage;
this.doingAndProcess = doingAndProcess;
this.monitorType = monitorType;
}
// 开启线程
public void start() {
if (thread == null) {
thread = new Thread(this);
thread.start(); // 启动线程
}
}
// 停止线程
public void stop() {
stopFlag = true;
}
// 扫描文件下载任务队列
private void imageScan() {
LogUtils.i(“+++ imageScan”);
// 获取文件下载任务
List webFileDoingList = storage.getDoingWebFileUrls();
while (webFileDoingList != null) {
try {
// 处理文件下载任务
doingAndProcess.doingProcess(webFileDoingList);
handler.sendEmptyMessage(0);
} catch (Exception e) {
e.printStackTrace();
} finally {
// 删除已处理完的任务
storage.removeDoingWebFileUrl(webFileDoingList);
}
webFileDoingList = storage.getDoingWebFileUrls();
}
}
// 扫描通用任务
private void taskScan() {
List taskList = storage.getDoingTasks();
while (taskList != null) {
try {
doingAndProcess.doingProcess(taskList);
Message msg = new Message();
if (taskList.size() > 0) {
msg.obj = taskList.get(0);
}
handler.sendMessage(msg);
} catch (Exception e) {
e.printStackTrace();
} finally {
storage.removeTask(taskList);
}
taskList = storage.getDoingTasks();
}
}
@Override
public void run() {
while (!stopFlag) {
if (monitorType == MONITOR_TYPE_IMAGE) {
imageScan();
} else if (monitorType == MONITOR_TYPE_TASK) {
taskScan();
}
try {
// 每200毫秒扫描一次任务队列
Thread.sleep(200);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public void addDoneAndProcess(int type, DoneAndProcess doneAndProcess) {
if (doneAndProcess != null) {
doneAndProcessMap.put(type, doneAndProcess);
}
}
}
任务队列如何实现?就是通过线程不断扫描任务列表,只要任务列表有任务就马上执行,关于任务会分两种,一种是图片下载任务,另一种是普通任务(发布微博、收藏微博、转发微博等)。当调用WorkQueueMonitor这个类的start方法就启动线程,然后执行run方法,根据不同任务类型执行任务。具体调用start方法的地方是在GlobalObject这个类里面。
/xiaowu_twitter/src/com/wwj/sina/weibo/GlobalObject.java
package com.wwj.sina.weibo;
import android.app.Activity;
import android.app.Application;
import com.weibo.net.Weibo;
import com.wwj.sina.weibo.interfaces.Const;
import com.wwj.sina.weibo.listener.AuthDialogListener;
import com.wwj.sina.weibo.net.PullFile;
import com.wwj.sina.weibo.object.Consumer;
import com.wwj.sina.weibo.workqueue.WorkQueueMonitor;
import com.wwj.sina.weibo.workqueue.WorkQueueStorage;
import com.wwj.sina.weibo.workqueue.task.TaskMan;
/**
-
全局对象Application级别
-
@author Administrator
*/
public class GlobalObject extends Application implements Const {
// 调试开关
public static final boolean DEBUG = true;
private Weibo weibo;
// 任务存储
private WorkQueueStorage workQueueStorage;
// 图像下载监视器
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
建议
当我们出去找工作,或者准备找工作的时候,我们一定要想,我面试的目标是什么,我自己的技术栈有哪些,近期能掌握的有哪些,我的哪些短板 ,列出来,有计划的去完成,别看前两天掘金一些大佬在驳来驳去 ,他们的观点是他们的,不要因为他们的观点,膨胀了自己,影响自己的学习节奏。基础很大程度决定你自己技术层次的厚度,你再熟练框架也好,也会比你便宜的,性价比高的替代,很现实的问题但也要有危机意识,当我们年级大了,有哪些亮点,与比我们经历更旺盛的年轻小工程师,竞争。
-
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!!!!!!!
-
准备想说怎么样写简历,想象算了,我觉得,技术就是你最好的简历
-
我希望每一个努力生活的it工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
-
有什么问题想交流,欢迎给我私信,欢迎评论
【附】相关架构及资料
资料领取
点击这里免费获取
内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术
经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。**
深知大多数初中级安卓工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Android移动开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-05V5iCWv-1710705190118)]
[外链图片转存中…(img-a0TXAc0F-1710705190118)]
[外链图片转存中…(img-x335UCFZ-1710705190119)]
[外链图片转存中…(img-RXAUmSAb-1710705190119)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Android)
[外链图片转存中…(img-Ev8bsTzw-1710705190120)]
建议
当我们出去找工作,或者准备找工作的时候,我们一定要想,我面试的目标是什么,我自己的技术栈有哪些,近期能掌握的有哪些,我的哪些短板 ,列出来,有计划的去完成,别看前两天掘金一些大佬在驳来驳去 ,他们的观点是他们的,不要因为他们的观点,膨胀了自己,影响自己的学习节奏。基础很大程度决定你自己技术层次的厚度,你再熟练框架也好,也会比你便宜的,性价比高的替代,很现实的问题但也要有危机意识,当我们年级大了,有哪些亮点,与比我们经历更旺盛的年轻小工程师,竞争。
-
无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!!!!!!!
-
准备想说怎么样写简历,想象算了,我觉得,技术就是你最好的简历
-
我希望每一个努力生活的it工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。
-
有什么问题想交流,欢迎给我私信,欢迎评论
【附】相关架构及资料
[外链图片转存中…(img-maRRSTsc-1710705190120)]
[外链图片转存中…(img-c40XQol3-1710705190120)]
资料领取
点击这里免费获取
内含往期Android高级架构资料、源码、笔记、视频。高级UI、性能优化、架构师课程、NDK、混合式开发(ReactNative+Weex)微信小程序、Flutter全方面的Android进阶实践技术