# **漫畫下載(章節下載)**
這個標題有點坑,其實是此次研究對象——漫畫APP的底層實現問題。
在其下載模塊,僅僅只進行了章節目錄下載,而未進行漫畫圖片下載,給讀者造成了一種假象,也給使用者造成了一種類似的假象:
使用者以為點擊下載,就已經成功的將漫畫資源保存至手機硬盤了。
> 你滿心歡喜,以為自己下載了一本書,其實,你只是下載了書皮和目錄。
真正的漫畫下載,只有選擇漫畫備份的時候,才會進行。
如果你關心漫畫圖片,是如何下載到手機硬盤上的,可以選擇閱讀《漫畫備份(圖片下載)》章節
如果你關心,漫畫APP是如何欺騙讀者——只下載了章節目錄,讓我們以為,閱讀漫畫時,漫畫的圖片,來自于手機硬盤,而不是網絡圖片——實際上閱讀的時候,是同步進行了圖片下載的操作——想了解這種騙人伎倆的背后原理,可以繼續往下閱讀。
## **目錄索引**
即將提到的文件
Serchactivity
Chapteractivity文件
detailactivity文件
detailpresenter文件
## **分析頁面路徑**
先請諸位跟隨我的指引,一步一步找到對應的文件
從APP界面入手:
第一步,進入搜索頁面——對應的是SerachActivity
第二步,進入搜索結果頁面——對應得以ResaultActivity
第三步,在搜索結果頁面選擇任意一款漫畫,進入漫畫詳情頁面——對應的是DetailsActivity
第四步,在漫畫詳情頁面的頂部,有一個下載按鈕,點擊下載按鈕,選擇要下載的章節;點擊對勾,開始下載——對應的是ChapterActivity
第五步,章節下載的實現類,是在DetailPresenter文件里,有一個addTask()函數,這,就是下載章節列表的核心代碼:
~~~
/**
* 添加任務到數據庫
* @param cList 所有章節列表,用于寫索引文件
* @param dList 下載章節列表
*/
public void addTask(final List<Chapter> cList, final List<Chapter> dList) {
mCompositeSubscription.add(Observable.create(new Observable.OnSubscribe<ArrayList<Task>>() {
@Override
public void call(Subscriber<? super ArrayList<Task>> subscriber) {
final ArrayList<Task> result = getTaskList(dList);
mComic.setDownload(System.currentTimeMillis());
mComicManager.runInTx(new Runnable() {
@Override
public void run() {
mComicManager.updateOrInsert(mComic);
for (Task task : result) {
task.setKey(mComic.getId());
mTaskManager.insert(task);
}
}
});
Download.updateComicIndex(mBaseView.getAppInstance().getContentResolver(),
mBaseView.getAppInstance().getDocumentFile(), cList, mComic);
subscriber.onNext(result);
subscriber.onCompleted();
}
}).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<ArrayList<Task>>() {
@Override
public void call(ArrayList<Task> list) {
RxBus.getInstance().post(new RxEvent(RxEvent.EVENT_TASK_INSERT, new MiniComic(mComic), list));
mBaseView.onTaskAddSuccess(list);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mBaseView.onTaskAddFail();
}
}));
}
~~~
有一個問題,想提問諸位讀者:
### **此處的章節下載,真的是下載嗎?**
思考三秒,1,2,3.
不,不是,并不是真的發起網絡請求操作,請求遠程主機。實際上,只是啟動了一個子線程,進行了SQL數據庫插入操作。
上述代碼有一句可以證明我的結論:
insert()函數
細心的讀者,可以點進去,看看insert的實現方式,看到Dao字樣,就足以證明我們的結論——此處,并沒有進行網絡請求操作,只進行了SQL數據庫插入操作。
如何進行SQL數據庫插入操作,將是greenDAO的知識,迫不及待的讀者,可以直接跳至《greenDAO》章節閱讀
### **既然此處沒有下載章節目錄,那此處的章節目錄,是源自哪里的呢?**
答案是:DetailActivity中的onTaskAddSuccess()函數
~~~
@Override
public void onTaskAddSuccess(ArrayList<Task> list) {
Intent intent = DownloadService.createIntent(this, list);
**startService(intent);**
updateChapterList(list);
showSnackbar(R.string.detail_download_queue_success);
hideProgressDialog();
}
~~~
此處啟動了一個Service的子類DownloadService,Service是Android系統的四大組件之一
在這里,我們只需要知道,在DetailActivity啟動之初,就同時啟動了DownloadService服務去下載章節列表,此時章節列表已經被存儲到手機硬盤當中,可以是FIle文件的形式,也可以是SQL數據庫文件的形式,主要在于開發者個人喜好來抉擇。
此時,漫畫下載之章節下載,已經非常清晰了。
唯一使得各位讀者迷惑的是:
1. 如何將網絡請求到的章節列表存儲到手機硬盤當中?
請看《文件讀寫必會——FIle》章節
2. 如何將其存儲到SQL文件當中?
請看《APP SQLlite數據操作——greenDAO》章節