Android图片上传队列Service
来源:互联网 发布:降维算法 编辑:程序博客网 时间:2024/04/29 02:46
需求描述
- 没有网络的时候,将操作产生的本地图片(拍照,也可能是其他文件),存储起来。有网络的时候传输到文件服务器。
- 文件服务器只支持一个文件一个文件的传输。
分析
- 因为文件上传的过程不依赖与界面,所以不考虑Activity开启子线程的方式,使用Service,并且App一开启就开启这个服务。
- 创建一个上传队列,每次队列有新的元素加入的时候就去通知Service上传队列改变
- 创建一个任务队列,每次一个上传任务执行完成后,改变任务状态然后通知Service任务状态改变
- Service负责维护这个需求主要逻辑。负责通维护通知栏状态变化,接收任务个数改变,任务状态改变的监听
流程逻辑图如下:
实现
demo
上传事件和事件队列
/** 上传任务 */public class PhotoUpload { // 任务状态 public static final int STATE_UPLOAD_COMPLETED = 5; public static final int STATE_UPLOAD_ERROR = 4; public static final int STATE_UPLOAD_IN_PROGRESS = 3; public static final int STATE_UPLOAD_WAITING = 2; public static final int STATE_SELECTED = 1; public static final int STATE_NONE = 0; private int mState; private String name; public int getUploadState() { return mState; } public void reset() { mState = STATE_NONE; } public void setUploadState(final int state) { if (mState != state) { mState = state; switch (state) { case STATE_UPLOAD_ERROR: case STATE_UPLOAD_COMPLETED: EventBus.getDefault().post(new UploadsModifiedEvent()); break; case STATE_SELECTED: case STATE_UPLOAD_WAITING: break; } notifyUploadStateListener(); } } private void notifyUploadStateListener() { EventBus.getDefault().post(new UploadStateChangedEvent(this)); }}
/** 上传事件队列 */public class PhotoUploadController { public static PhotoUploadController getFromContext(Context context) { return MyApp.getApplication(context).getPhotoUploadController(); } private final Context mContext; private final ArrayList<PhotoUpload> mSelectedPhotoList; private final ArrayList<PhotoUpload> mUploadingList; public PhotoUploadController(Context context) { mContext = context; mSelectedPhotoList = new ArrayList<PhotoUpload>(); mUploadingList = new ArrayList<PhotoUpload>(); } // 添加任务方法 public boolean addUpload(PhotoUpload selection) { if (null != selection) { synchronized (this) { if (!mUploadingList.contains(selection)) { selection.setUploadState(PhotoUpload.STATE_UPLOAD_WAITING); mUploadingList.add(selection); mSelectedPhotoList.remove(selection); postEvent(new UploadsModifiedEvent()); return true; } } } return false; } public synchronized int getActiveUploadsCount() { int count = 0; for (PhotoUpload upload : mUploadingList) { if (upload.getUploadState() != PhotoUpload.STATE_UPLOAD_COMPLETED) { count++; } } return count; } /* 获取下一个任务 */ public synchronized PhotoUpload getNextUpload() { for (PhotoUpload selection : mUploadingList) { if (selection.getUploadState() == PhotoUpload.STATE_UPLOAD_WAITING) { return selection; } } return null; } public synchronized List<PhotoUpload> getUploadingUploads() { return new ArrayList<PhotoUpload>(mUploadingList); } public synchronized int getUploadsCount() { return mUploadingList.size(); }}
EventBus 通讯
主要包括两种类型的通讯
- 任务暂停事件
- 上传状态改变;上传失败、上传成功、上传错误、暂停
/** 上传任务状态改变 */public class UploadStateChangedEvent { private final PhotoUpload mUpload; public UploadStateChangedEvent(PhotoUpload upload) { mUpload = upload; } public PhotoUpload getUpload() { return mUpload; }}
public class UploadingPausedStateChangedEvent { // 空实现 直接开始下一个任务即可}
想到但是还没实现的通讯:移除一个上传任务
所以在Service中存在两个EventBus监听方法
// 监听任务状态 public void onEventMainThread(UploadStateChangedEvent event) { PhotoUpload upload = event.getUpload(); switch (upload.getUploadState()) { case PhotoUpload.STATE_UPLOAD_IN_PROGRESS: updateNotification(upload); break; case PhotoUpload.STATE_UPLOAD_COMPLETED: mNumberUploaded++; case PhotoUpload.STATE_UPLOAD_ERROR: startNextUploadOrFinish(); case PhotoUpload.STATE_UPLOAD_WAITING: break; } } // 监听手动改变任务public void onEvent(UploadingPausedStateChangedEvent event) { if (isUploadingPaused(this)) { stopUploading(); } else { startNextUploadOrFinish(); } }
具体单个上传任务执行
具体使用
private boolean mCurrentlyUploading; private ExecutorService mExecutor = Executors.newSingleThreadExecutor(); private Future<?> mCurrentUploadRunnable;
申明任务
public abstract class PhotupThreadRunnable implements Runnable { public final void run() { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); runImpl(); } public abstract void runImpl(); protected boolean isInterrupted() { return Thread.currentThread().isInterrupted(); }}
具体实现
private class UpdateRunnable extends PhotupThreadRunnable { private final PhotoUpload mSelection; public UpdateRunnable(PhotoUpload selection) { mSelection = selection; } public void runImpl() { try { if (mSelection.getUploadState() == PhotoUpload.STATE_UPLOAD_WAITING) { mSelection .setUploadState(PhotoUpload.STATE_UPLOAD_IN_PROGRESS); // 暂停1秒 模拟上传 Thread.sleep(1000); // TODO 在这里配置文件服务器地址和参数,需要上传的文件 使用公司文件服务器测试通过 RequestParams params = new RequestParams( "https://www.baidu.com/"); params.addBodyParameter("f", new File("文件路径")); x.http().post(params, new CommonCallback<String>() { @Override public void onSuccess(String result) { mSelection .setUploadState(PhotoUpload.STATE_UPLOAD_COMPLETED); } @Override public void onError(Throwable ex, boolean isOnCallback) { mSelection .setUploadState(PhotoUpload.STATE_UPLOAD_ERROR); } @Override public void onCancelled(CancelledException cex) { mSelection .setUploadState(PhotoUpload.STATE_UPLOAD_WAITING); } @Override public void onFinished() { // 通知service bus.post(new UploadingPausedStateChangedEvent()); } }); } } catch (InterruptedException e) { e.printStackTrace(); } } }
维护通知栏
private void startForeground() { if (null == mNotificationBuilder) { mNotificationBuilder = new android.support.v4.app.NotificationCompat.Builder( this); mNotificationBuilder.setSmallIcon(R.drawable.ic_launcher); mNotificationBuilder.setContentTitle(getString(R.string.app_name)); mNotificationBuilder.setOngoing(true); mNotificationBuilder.setWhen(System.currentTimeMillis()); PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); mNotificationBuilder.setContentIntent(intent); } startForeground(12, mNotificationBuilder.build()); } void updateNotification(final PhotoUpload upload) { String text; switch (upload.getUploadState()) { case PhotoUpload.STATE_UPLOAD_WAITING: text = "上传: " + upload.getName(); mNotificationBuilder.setContentTitle(text); mNotificationBuilder.setTicker(text); mNotificationBuilder.setProgress(0, 0, true); mNotificationBuilder.setWhen(System.currentTimeMillis()); break; case PhotoUpload.STATE_UPLOAD_IN_PROGRESS: text = "上传: " + upload.getName(); mNotificationBuilder.setContentTitle(text); mNotificationBuilder.setTicker(text); mNotificationBuilder.setProgress(0, 0, true); mNotificationBuilder.setWhen(System.currentTimeMillis()); break; } mNotificationMgr.notify(12, mNotificationBuilder.build()); }
Demo
下载地址
0 0
- Android图片上传队列Service
- Android图片上传队列Service
- android图片压缩上传系列-service篇
- 利用Web Service进行远程上传图片
- swift3.0 队列请求(上传图片)
- iOS网络串行队列之图片上传
- Android 选择图片、上传图片
- Android URL上传图片
- android HttpClient 上传图片
- android HttpClient 上传图片
- android图片上传
- android图片上传服务器
- android上传图片
- android 上传图片
- android图片压缩上传
- Android 图片压缩上传
- Android 上传图片
- Android Base64上传图片
- 利用zlib库对HTTP收到的gzip数据解压
- 今天碰到的问题
- Spring整合JMS
- linux - echo
- springMVC@RequetMapping无法url映射方法问题
- Android图片上传队列Service
- 动态链接库使用.def导出一个c++类的函数
- 第一次前端电面面经分享(补充答案中)
- 如何在Eclipse中自定义类似syso的快捷代码模板
- 谈为什么一个java源文件中只能有一个public类?
- 理解Java垃圾回收机制
- 数据库基础知识 关系
- asp.net 另打开窗口
- linux 安装libsvm 并配置python