# **漫画下载(章节下载)**
这个标题有点坑,其实是此次研究对象——漫画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》章节