스스로 바퀴 를 만 들 고 다운로드 관리 자 를 쓴다(3)
네트워크 요청,다운로드 진도,스 레 드 등 관건 적 인'부품'을 작성 한 후에 우리 가 지금 해 야 할 일 은 이 부품 들 을 핵심 뼈 대 를 통 해 연결 하여 호출 하기에 편리 하 다 는 것 이다.이 는
Java
의
와 비슷 하 게 하나 이상Class
이 구성 요소 들 의 논리 적 운행 을 책임 져 야 한다.현재,우 리 는 이러한 직책 을 완성 하 는Class
을 작성 해 야 합 니 다.여 기 는DownloadManager.java
이 라 고 명명 합 니 다. /**
* Created by mid1529 on 2016/12/19.
*
*/
public final class DownloadManager {
private static final String TAG = "DownloadManager";
public static final int HANDLER_DOWNLOAD_COMPLETED = 0x234123;
public static final int HANDLER_DOWNLOAD_FAILED = 0x12345234;
public static final int HANDLER_DOWNLOAD_PROGRESS = 0x2052344;
public static final int HANDLER_DOWNLOAD_CALL = 0x4234134;
@SuppressLint("StaticFieldLeak")
private static DownloadManager ourInstance = new DownloadManager();
private SQLiteDao mSQLiteDao = null;
private ArrayMap mDownloadTaskQueue = null; //
private ArrayMap mDownloadTaskCallQueue = null;
private DownloadService.DownloadServiceBinder mDownloadServiceBinder = null;
private ServiceConnection mServiceConnection = null;
private Application mApplication = null;
private DownloadCallback mDownloadCallback = null;
private DownloadHandler mHandler = null;
private boolean mIsDeleteHistory = false;
private ExecutorService mCachedThreadPool = null;
public synchronized static DownloadManager getInstance() {
if (ourInstance == null) {
synchronized (DownloadManager.class) {
ourInstance = new DownloadManager();
}
}
return ourInstance;
}
private DownloadManager() {
mDownloadTaskQueue = new ArrayMap<>();
mDownloadTaskCallQueue = new ArrayMap<>();
}
/**
* Application
* ,
*
* @param app Application
* @return DownloadManager
*/
public synchronized DownloadManager startService(Application app) {
if (mServiceConnection != null && mApplication != null)
return ourInstance;
mHandler = new DownloadHandler();
mCachedThreadPool = Executors.newCachedThreadPool();
mApplication = app;
Intent intent = new Intent(app, DownloadService.class);
mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
try {
mDownloadServiceBinder = (DownloadService.DownloadServiceBinder) iBinder;
mDownloadServiceBinder.setHandler(mHandler);
} catch (Exception e) {
e.printStackTrace();
onDestory();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
onDestory();
}
};
app.startService(intent);
app.bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
mSQLiteDao = new SQLiteDao(app);
return ourInstance;
}
/**
* , ,
* url、filename ,
*
* @param task
* @return
*/
public boolean addTaskToQueue(DownloadTask task) {
if (!isDownloadTaskLegal(task)) //
return false;
checkInited();
DownloadTask query = mSQLiteDao.queryTask(task);
task.setPause(false);
if (query == null) {// , ,
mSQLiteDao.insertDownloadTask(task);
query = mSQLiteDao.queryTask(task);
task.setTaskId(query.getTaskId());
mDownloadTaskQueue.put(query.getTaskId(), query);
mDownloadServiceBinder.startDownload(task);
} else {
task.setTaskId(query.getTaskId());
if (mDownloadTaskQueue.get(task.getTaskId()) == null) {
task.setPause(false);
mDownloadTaskQueue.put(task.getTaskId(), task);
mDownloadServiceBinder.startDownload(task);
}
}
return true;
}
/**
*
*
* @param downloadTask
* @return
*/
@SuppressWarnings("RedundantIfStatement")
private boolean isDownloadTaskLegal(DownloadTask downloadTask) {
if (TextUtils.isEmpty(downloadTask.getFileName()))
return false;
if (TextUtils.isEmpty(downloadTask.getUrl()))
return false;
if (HttpUrl.parse(downloadTask.getUrl()) == null)
return false;
return true;
}
/**
* ,
*
* @param task
*/
public void pauseDownload(DownloadTask task) {
task.setPause(true);
removeTaskFromQueue(task, false);
}
/**
*
*
* @param downloadTask
* @param isDeleteDbHistory
*/
private void removeTaskFromQueue(final DownloadTask downloadTask, boolean isDeleteDbHistory) {
if (downloadTask.getTaskId() == null)
return;
DownloadTask task = mDownloadTaskQueue.get(downloadTask.getTaskId());
if (task != null) {
mDownloadTaskQueue.remove(task.getTaskId());
}
Call call = mDownloadTaskCallQueue.get(downloadTask.getTaskId());
if (call != null) {
call.cancel();
}
if (isDeleteDbHistory) { //
//noinspection ConstantConditions
mCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
mSQLiteDao.deleteDownloadTaskByKey(downloadTask.getTaskId());
}
});
}
}
private void addCallToQueue(Long taskId, Call call) {
mDownloadTaskCallQueue.put(taskId, call);
}
/**
* , , ,
*/
public void stopService() {
checkInited();
mDownloadTaskQueue.clear();
removeDownloadCallback();
if (mApplication == null)
return;
mApplication.stopService(new Intent(mApplication, DownloadService.class));
mApplication.unbindService(mServiceConnection);
}
/**
*
* Handler
*
* null
*
*/
private void onDestory() {
mHandler.removeCallbacksAndMessages(null);
mSQLiteDao = null;
mDownloadTaskQueue.clear(); //
mDownloadTaskCallQueue.clear();
mDownloadServiceBinder = null;
mServiceConnection = null;
mCachedThreadPool.shutdown();
mCachedThreadPool = null;
mApplication = null;
}
/**
* start() ,
*/
private void checkInited() {
if (mDownloadServiceBinder == null) {
throw new NullPointerException("Do you remember invok \"DownloadManager.getInstance().start()\" in your Application.class? ");
}
}
/**
* @return Dao
*/
public List getDownloadTask() {
checkInited();
return mSQLiteDao.queryAllTask();
}
/**
*
*
* @param callback
*/
public void setDownloadCallback(DownloadCallback callback) {
this.mDownloadCallback = callback;
}
/**
*
*/
public void removeDownloadCallback() {
this.mDownloadCallback = null;
}
/**
*
*
* @param downloadTask
*/
private void updateDownloadTask(final DownloadTask downloadTask) {
mCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
mSQLiteDao.updateDownloadTask(downloadTask);
}
});
}
/**
*
*
* @param downloadTask
*/
private void cleanDownloadInfo(final DownloadTask downloadTask) {
mCachedThreadPool.execute(new Runnable() {
@Override
public void run() {
removeTaskFromQueue(downloadTask, mIsDeleteHistory);
}
});
}
/**
* ,
*
* @return
*/
public boolean isDeleteHistory() {
return mIsDeleteHistory;
}
/**
*
*
* @param deleteHistory
*/
public void setDeleteHistory(boolean deleteHistory) {
mIsDeleteHistory = deleteHistory;
}
/**
* Handler
*/
@SuppressWarnings("unchecked")
private static class DownloadHandler extends Handler {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case HANDLER_DOWNLOAD_PROGRESS:
getInstance().updateDownloadTask((DownloadTask) msg.obj);
getInstance().mDownloadCallback.onProgress((DownloadTask) msg.obj);
break;
case HANDLER_DOWNLOAD_COMPLETED:
getInstance().cleanDownloadInfo((DownloadTask) msg.obj);
getInstance().mDownloadCallback.onComplete((DownloadTask) msg.obj);
break;
case HANDLER_DOWNLOAD_FAILED:
getInstance().cleanDownloadInfo((DownloadTask) msg.obj);
getInstance().mDownloadCallback.onDownloadFaild((DownloadTask) msg.obj);
break;
case HANDLER_DOWNLOAD_CALL:
if (msg.obj instanceof ArrayMap) {
ArrayMap map = (ArrayMap) msg.obj;
if (map.size() != 0) {
getInstance().addCallToQueue(map.keyAt(0), map.get(map.keyAt(0)));
}
}
break;
}
}
}
}
전형 적 인 것 은 하나의 App 에 하나의 다운로드 관리 인 스 턴 스 만 필요 하기 때문에 우 리 는 하나의 예 모드 로
DownloadManager
인 스 턴 스 를 가 져 온 다음 에 통신 을 할 수 있 습 니 다.관심 있 는 참고 주석 읽 기.총결산
이 프로젝트 에서 네트워크
Header
의 데 이 터 를 추출 할 때
로 추출 합 니 다.예 를 들 어Range
이런 방법 은 과학적 이지 않 지만 어떤 방법 으로 얻 을 수 있 는 지 모 르 겠 습 니 다.여기 서 겸손 하고 겸손 합 니 다.누가 과학적 인 방법 을 알려 줄 수 있 습 니까?전체적인 사고방식 은 이렇다.지금 은V0.2
버 전 일 뿐 엄밀 하지 않 은 곳 이 많 고 게 으 름 을 피 우 는 곳 이 많 으 니 이틀 후에 개선 하 자.플 로 차 트 및 전체 Project 는 일요일 에 GitHub 에 넣 습 니 다.관심 있 는 것 은 보 실 수 있 습 니 다.
여기까지 3 일간 의 수문 을 끝 낸 셈 이 니 조용히 글 을 쓰 는 것 이 쉽 지 않 으 니 잘 버 텨 보 자.
Lolipop
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.