ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# **漫画下载(章节下载)** 这个标题有点坑,其实是此次研究对象——漫画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》章节