失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android小说阅读器智能断章功能的实现

android小说阅读器智能断章功能的实现

时间:2022-08-23 01:30:18

相关推荐

android小说阅读器智能断章功能的实现

前言

【转载请注明出处】:/ProgramChangesWorld/article/details/47209475

不知道自己突然发什么神经,有想写一个小说阅读器的冲动,想写那种从网站获取资源的在线小说和本地txt文件打开的功能,然后自己就开始规划该怎么去做。先做本地的吧,首先要解决的问题是如何实现智能断章的功能,一般来说小说阅读器都有这个功能,如果这个没法实现那么做出来就没啥意思了。于是我开始疯狂的搜码,花费了大半天之后,看了许多的博客和源码可是还是没有找到关于智能断章的内容,可能做阅读器的人不多吧,从网上找现成的代码被pass了,那就只能自己琢磨了。

自己写还是很痛苦的,因为要考虑的内容很多,或者说刚开始一点思路都没有,完全不知道该怎么下手,虽然知道肯定要用正则表达式,但是哪来的字符串让我来匹配啊!!如果把全部的内容都读取出来放在一个字符串里 ,哦,我可以想象那个字符串的长度了~~

但是我还确实那么干了,因为暂时没想到更好的处理方法。不过结果”还挺好“,因为我打开一个几十K的txt文件,真的确实给打开了,运行没问题,然后我又试了一个10M的文件,哈哈,崩溃了,内存溢出。。。。

因为这次错误,让我明白了这个方法行不通,不是什么都可以暴力解决的,所以就换了其他的思路,中间也想了另一种方法,但是有一点瑕疵,就是章节不能完全对上,有时章节的名称会少一两个字或者出现一点乱码,虽然大体没问题,但是被我放弃了,因为还不到将就的地步。

在痛苦了一个晚上之后,突然就来了所谓的灵感了吧,问题也就是在那之后的几个小时解决的,所以我总结出了一个道理,要学会放弃,因为可能会有更好的在等着你。如果我继续想着去改上一种方法的瑕疵,或许就会和这种方法擦肩而过。

啰嗦话可能说的有点多了,算是有一点感触吧,为了这个功能真是浪费了两天的时间,而且阅读器这个软件还不一定能做,因为种种原因,把这个想问题的过程给记录下来也算是有一个交代吧。。

标题

接下来我就说说我当时是怎么想的,先看一下效果图吧:

可以看到,能够正常的得到所有的目录了,当点击了章节目录之后,就会看到内容。。。当运行这个程序的时候知道把一本电子书改名为book.txt然后放在根目录就可以了。

好了,开始讲实现的过程了。

因为如果你把所有的字符都导入到一个字符串的话,那将是非常的庞大的字符串,可能是百万级别的,如果直接存储的话内存可能就会溢出,因为内存没有那么大。那么该怎么办呢?我的一个思路就是把百万级别的字符串分成一千份,一份也就是1000级别的字符串,这样的话,内存还是可以接受的,我们只需要对每一份字符串进行匹配,得到章节的名字,然后得到章节的内容,将它们存到数据库之中即可。

思路是这样,但是实现起来还有有点小问题,当然现在再去看这些代码可能就比较简单了。

【1】怎么去得到那1000级别的字符串呢?直接用字节输入流去做吗?(虽然我还没试过)我用的是网上很多人都在用的一个类:BookPageFactory,这个类能够基本实现我的要求,我把它不用的东西去掉,只留下了几个方法而已。

readParagraphForward(int pos):这个方法的作用是从位置为pos的字节开始,读取一个段落的内容,所谓的一个段落就是出现回车换行的字符,因为一般每一章节的标题都是在换行处,这个是必须的。这个方法的具体实现我就不说了,网上都有相关的代码,大家可以自己找去看看。

得到一个段落的内容之后,它返回的是一个字节数组,我们要把它转换成一个字符串,然后我们判断这个字符串的length是不是大于1000,如果是,那么我们就得到了这个字符串,如果不是,我们就再继续得到下一个段落的内容,然后将内容相连接,知道长度大于1000位置,得到了字符串之后,我们就进行第二步。

【2】章节目录的正则表达式该怎么写呢?因为要找出章节的话就必须要使用正则表达式,但是,写不出正则表达式的话什么都是白搭。翻阅了关于正则表达式的课本恶补了一下内容,我就写出了下面的正则表达式:

String regex = “第.{1,7}章.{0,}\r\n”;

我就说明一下:首先是“第”,这个不用讲,然后是“.{1,7}”,这个意思是说“.”代表任意字符,并且只出现1-7次。因为我估计章节最多只有几千章,比如“第九千八百七十六章”,在“第”和”章“之间只有7个字符,也即是说最多只有7个字符。然后就是“章”之后的“.{0,}”这个代表章节的名字,比如上图中所示的“陨落的天才”,“\r\n”代表的就是回车了,因为一般来说章节都是占一行的,不会在章节的后面直接来正文。这样我们就写好了正则表达式,然后就可以使用Pattern和Matcher来进行匹配得到相应的内容,如果对字符串的匹配不太了解的话,可以先去补充相关的知识。

【3】得到标题和内容,如果1000级别的字符串里面有章节标题的话,那么我们可以直接匹配出来,然后调用Matcher的group()方法就可以得到章节标题了,难的是怎么得到章节的内容,因为按照我的思路来说是得到章节内容及标题,然后放在数据库里,然后下次阅读的时候直接从数据库的读取,我的思路是按照这个来进行的。这里图解一下可能比较好:

可以看到,第一章的内容是从第一个1000级别的字符串的标题最后到第二个字符串的从开始到“第”结束之间的内容,两者加起来就是第一章的内容,图中显示的是“第一章”,代表的是“第一章 陨落的天才”,标题我就没有打上去,以此类推。

可能出现的情况就是1000级别的字符串里面不匹配章节内容,如图中第三个字符串所示,那么此时第二章的内容就是s3+s4+s5,一般就是这两种情况,我们得到章节的内容之后就和标题一起存到数据库里面,下一次直接从数据库读取内容,当然还有其他的思路,不过我暂时是打算这么办。

小结

实现思路如上,需要注意的就是下面几点:

不能直接读取整个文件内容到一个字符串里面,会造成内存溢出,分成几千份,重复利用一个1000级别的字符串正则表达的书写,是能够实现的关键,如果不能匹配的好的话,就会匹配不到或者匹配的内容或多或少对每一个字符串是否匹配章节标题来考虑,如果不匹配该如何处理

因为我的语言组织能力不是太好,可能说的不是太清楚,如果让大家有困惑的地方,欢迎大家和我交流。

【源码下载】

如果觉得《android小说阅读器智能断章功能的实现》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。