本人能力有限,暂时不能更新了,等有时间再深入多线程Service研究。
/**
* DownloadManager
*
* @author Edwin.Wu
* @version 2017/1/16 15:27
* @since JDK1.8
*/
public class DownloadManager {
private static DownloadManager instance;
private final Context context;
private DownloadManager(Context context) {
this.context = context;
context.startService(new Intent(context, DownLoadService.class));
}
public static DownloadManager getInstance(Context context) {
if (instance == null) {
synchronized (DownloadManager.class) {
if (instance == null) {
instance = new DownloadManager(context);
}
}
}
return instance;
}
public void down(DownLoadBean item) {
Intent intent = new Intent(context, DownLoadService.class);
intent.putExtra(Constants.KEY_DOWNLOAD_ENTRY, item);
intent.putExtra(Constants.KEY_OPERATING_STATE, false);
context.startService(intent);
}
public void delete(DownLoadBean item) {
Intent intent = new Intent(context, DownLoadService.class);
intent.putExtra(Constants.KEY_DOWNLOAD_ENTRY, item);
intent.putExtra(Constants.KEY_OPERATING_STATE, true);
context.startService(intent);
}
}
/**
* 下载服务
*
* @author Edwin.Wu
* @version 2017/1/12 10:43
* @since JDK1.8
*/
public class DownLoadService extends Service {
private String TAG = DownLoadService.this.getClass().getName();
/**
* 用于记录所有下载的任务,方便在取消下载时,通过id能找到该任务进行删除
*/
private ConcurrentHashMap<String, DownLoadTask> mTaskMap = new ConcurrentHashMap<String, DownLoadTask>();
private ThreadPoolExecutor downLoadExecutor = (ThreadPoolExecutor) Executors.newCachedThreadPool();
private LinkedBlockingDeque<DownLoadBean> mWaitingQueue = new LinkedBlockingDeque<>();
/**
* 当下载状态发送改变的时候回调
*/
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
DownLoadBean bean = (DownLoadBean) msg.obj;
int what = msg.what;
switch (what) {
case DownLoadState.STATE_ERROR:
case STATE_DOWNLOADED:
case STATE_DELETE:
case DownLoadState.STATE_PAUSED:
Log.e("Message", "---> " + bean.toString());
mTaskMap.remove(bean.id);
DownLoadBean poll = mWaitingQueue.poll();
if (poll != null) {
downNone(poll);
}
break;
default:
break;
}
DownLoadObservable.getInstance().setData(bean);
}
};
/**
* 当下载状态发送改变的时候调用
*/
private void notifyDownloadStateChanged(DownLoadBean bean, int state) {
Message message = handler.obtainMessage();
message.obj = bean;
message.what = state;
handler.sendMessage(message);
}
/**
* 下载
*
* @param loadBean object
*/
public void download(DownLoadBean loadBean) {
//TODO 先判断是否有这个app的下载信息,更新信息
if (DataBaseUtil.getDownLoadById(getApplicationContext(), loadBean.id) != null) {
DataBaseUtil.UpdateDownLoadById(getApplicationContext(), loadBean);
} else {
//TODO 插入数据库
DataBaseUtil.insertDown(getApplicationContext(), loadBean);
}
int state = loadBean.downloadState;
switch (state) {
case DownLoadState.STATE_NONE://默认
downNone(loadBean);
break;
case DownLoadState.STATE_WAITING://等待中
downWaiting(loadBean);
break;
case DownLoadState.STATE_PAUSED://暂停
downPaused(loadBean);
break;
case DownLoadState.STATE_DOWNLOADING://下载中
downLoading(loadBean);
break;
case DownLoadState.STATE_CONNECTION://连接中
break;
case DownLoadState.STATE_ERROR://下载失败
downError(loadBean);
break;
case STATE_DOWNLOADED://下载完毕
Toast.makeText(BaseApplication.mContext, loadBean.appName + "->下载完毕", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
Log.e(TAG, "IBinder");
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.e(TAG, "onStartCommand");
//TODO 执行
if (intent != null) {
DownLoadBean bean = (DownLoadBean) intent.getSerializableExtra(Constants.KEY_DOWNLOAD_ENTRY);
if (bean != null) {
boolean booleanExtra = intent.getBooleanExtra(Constants.KEY_OPERATING_STATE, false);
if (booleanExtra) {
//TODO 删除下载
deleteDownTask(bean);
} else {
//TODO 开始下载
download(bean);
}
}
}
return super.onStartCommand(intent, flags, startId);
}
public void deleteDownTask(DownLoadBean item) {
//TODO 删除文件,删除数据库
try {
DownLoadTask remove = mTaskMap.remove(item.id);
if (remove != null) {
remove.cancle();
} else {
mWaitingQueue.remove(item);
}
item.downloadState = STATE_DELETE;
DataBaseUtil.DeleteDownLoadById(getApplicationContext(), item.id);
notifyDownloadStateChanged(item, STATE_DELETE);
} catch (Exception e) {
e.printStackTrace();
}
}
private void downNone(DownLoadBean loadBean) {
//TODO 最最最--->先判断任务数是否
if (mTaskMap.size() >= DownLoadConfig.getConfig().getMax_download_tasks()) {
mWaitingQueue.offer(loadBean);
loadBean.downloadState = DownLoadState.STATE_WAITING;
//TODO 更新数据库
DataBaseUtil.UpdateDownLoadById(getApplicationContext(), loadBean);
//TODO 每次状态发生改变,都需要回调该方法通知所有观察者
notifyDownloadStateChanged(loadBean, DownLoadState.STATE_WAITING);
} else {
if (loadBean.totalSize <= 0) {
ConnectThread connectThread = new ConnectThread(getApplicationContext(),
handler, mTaskMap, downLoadExecutor, loadBean);
downLoadExecutor.execute(connectThread);
} else {
DownLoadTask downLoadTask = new DownLoadTask(getApplicationContext(),
handler, mTaskMap, loadBean);
mTaskMap.put(loadBean.id, downLoadTask);
downLoadExecutor.execute(downLoadTask);
}
}
}
/**
* 等待状态
*/
private void downWaiting(DownLoadBean loadBean) {
//TODO 1.移出去队列
mWaitingQueue.remove(loadBean);
Log.e("Edwin", "mWaitingQueue size = " + mWaitingQueue.size());
//TODO 2.TaskMap获取线程对象,移除线程;
DownLoadTask downLoadTask = mTaskMap.get(loadBean.id);
if (downLoadTask != null)
downLoadTask.cancle();
mTaskMap.remove(loadBean.id);
//TODO 3.状态修改成STATE_PAUSED;
loadBean.downloadState = DownLoadState.STATE_PAUSED;
//TODO 4.更新数据库
DataBaseUtil.UpdateDownLoadById(getApplicationContext(), loadBean);
//TODO 5.每次状态发生改变,都需要回调该方法通知所有观察者
notifyDownloadStateChanged(loadBean, DownLoadState.STATE_PAUSED);
}
/**
* 暂停状态
*/
private void downPaused(DownLoadBean loadBean) {
//TODO 1.状态修改成STATE_WAITING;
loadBean.downloadState = DownLoadState.STATE_WAITING;
downNone(loadBean);
}
/**
* 下载状态
*/
private void downLoading(DownLoadBean loadBean) {
//TODO 1.TaskMap获取线程对象,移除线程;
DownLoadTask downLoadTask = mTaskMap.get(loadBean.id);
if (downLoadTask != null) {
downLoadTask.cancle();
mTaskMap.remove(loadBean.id);
} else {
mWaitingQueue.remove(loadBean);
}
// //TODO 2.状态修改成STATE_PAUSED;
// loadBean.downloadState = DownLoadState.STATE_PAUSED;
// notifyDownloadStateChanged(loadBean, DownLoadState.STATE_PAUSED);
}
/**
* 下载失败
*/
private void downError(DownLoadBean loadBean) {
//TODO 1.删除本地文件文件
Log.i("Edwin", "删除本地文件文件 Id = " + loadBean.id);
//TODO 2.更新数据库数据库
DataBaseUtil.UpdateDownLoadById(getApplicationContext(), loadBean);
loadBean.downloadState = DownLoadState.STATE_NONE;
// /*********以下操作与默认状态一样*********/
// //TODO 4.状态修改成STATE_WAITING;
// //TODO 5.创建一个线程;
// //TODO 6.放入TaskMap集合;
// //TODO 7.启动执行线程execute
download(loadBean);
}
@Override
public void onDestroy() {
Log.e(TAG, "onDestroy");
super.onDestroy();
}
}
热门源码