by hzwusibo 20190301
一、sdk簡介:
二、epub科普
三、解析器sdk設計
四、epub解析的原理:
五、sdk如何接入與基本使用
一、sdk簡介:
a、目前支持的格式: 標準epub,? 云閱讀定制epub, html, doc, txt,? umd等格式。
b、作用: 解析主要作用在于獲取書籍基本信息、解析章節內容。
書籍打開流程(解析、繪制等)如下圖所示:
c、解析器sdk用例圖:
二、epub科普(此處很有必要,插播一段epub的科普,已經熟悉的可以跳過此段)
a、? epub全稱為Electronic Publication的縮寫,意為:電子出版, epub于2007年9月成為國際數位出版論壇(IDPF)的正式標準,以取代舊的開放Open eBook電子書標準。 一個 EPUB 就是一個簡單 ZIP 格式文件(使用 .epub 擴展名),其中包括按照預先定義的方式排列的文件。(EPUB 非常簡單。只需將后綴改為.zip或.rar,解壓即可看到里面的文件內容)。
一個epub電子書的zip大致包含以下東西:
1、每一本epub電子書均包含一個名為mimetype的文件,且內容不變,用以說明epub的文件格式。
2、META-INF用于存放容器信息,該目錄包含一個文件,即container.xml。(container.xml的主要功能用于告訴閱讀器,電子書的根文件(rootfile)的路徑和打開放式,一般來講,該container.xml文件也不需要作任何修改,除非你改變了根文件的路徑和文件名稱)。
3、 OEBPS目錄用于存放OPS文檔、OPF文檔、NCX文檔、CSS文檔等( OEBPS這個名字是可變的,可以根據containter.xml進行配置)。
OEBPS目錄包含了:
image子目錄(不一定總有)存放了所有的圖片文件
content.opf , OPF文檔是epub電子書的核心文件,且是一個標準的XML文件,依據OPF規范
toc.ncx 目錄文件,ncx文件是epub電子書的又一個核心文件,用于制作電子書的目錄,其文件的命名通常為toc.ncx。
一些xhtml或html文件。就是書的內容。
b、? content.opf:
包括四個元素:metadata, manifest, spine, guide
(1)metadata: epub的元數據,如title、language、identifier、cover等。其中title 和 identifier這兩個數據是必須的。
(2)manifest:列出了目錄中所包含的所有文件(xhtml、css、png、ncx等)。
(3)spine:所有xhtml文檔的線性閱讀順序。其中,spine標簽的toc屬性必須包含在manifest列出來的.ncx的id??梢詫?OPF spine 理解為是書中 “頁面” 的順序,解析的時候按照文檔順序從上到下依次讀取 spine。
c、toc.ncx
ncx 定義了數字圖書的目錄表。復雜的圖書中,目錄表通常采用層次結構,包括嵌套的內容、章和節。
d、spine和ncx文件有什么不同?(后面經常用到)
Spine標簽描述文檔順序,ncx文件描述目錄。
兩者很容易混淆,因為兩個文件都描述了文檔的順序和內容。要說明兩者的區別,最簡單的辦法就是拿印刷書來打比方:.opf文件的spine標簽描述了書中的各個章節是如何實際連接起來的,比方說翻過第一章的最后一頁就看到第二章的第一頁。.ncx在圖書的一開始描述了目錄,目錄肯定會包含書中主要的章節,但是還可能包含沒有單獨分頁的小節。(一條法則是ncx包含的 navPoint 元素通常比 opf spine中的itemref 元素多。實際上,spine 中的所有項都會出現在 .ncx 中,但.ncx可能更詳細。)
參考文獻:https://www.cnblogs.com/diligenceday/p/4999315.html
三、解析器sdk設計
a、類圖:
IParser 為解析器接口 (解析器對外提供的方法都在此),? BookParser幫助接入端獲取書籍解析器對象,包含很多get方法(如 getPrisOfOnlineEpubParser()獲取云閱讀定制epub解析器,getTxtParser()獲取txt解析器,getEpubParser()標準epub書籍解析器等)獲取解析器后能夠使用IParser中提供的方法,進行解析與獲取章節的內容。? 所有的解析器都繼承了抽象父類ParserBase(解析器公共的方法在父類中實現,子類繼承父類只需要實現各自不同的部分,如iniBook(), getChapter()方法等)。
ps.? 接入端可以傳入IMyNCXReader接口的實現類給PrisOfOnlineEpubParser進行外部解析目錄、書籍信息等任務。
b、工程結構:?
對外部分:
IParser解析器接口
BookParser獲取書籍解析器對象
ICacheHelp設置解析存儲(緩存)地址(書籍文件所在地址、 接入時候需要設置解析后文件存儲地址等)
ILogHelp設置Log日志(打印log日志)
云閱讀epub解析器除了支持解析epub中目錄,也可以由接入端進行解析, 必須實現ISrNCXReader接口,例如蝸牛自己實現(接入端),云閱讀解析epub中目錄l實現)。
對內部分:
book包主要是解析的具體實現
cache包為緩存
log包為日志
parser包里是各種解析器類(當前支持的解析器類型)
util包為工具類。
c、解析器中二個重要的model類(Book和 Navpoint)
其中Book為書籍基本信息model類, Navpoint目錄orSpine基本信息model類。
(1) Book 書的信息包括書名, 作者, 封面,目錄結構等。
解析器解析書籍信息賦值給Book類的對象,如epub的基本信息、封面信息、目錄等。
關健代碼:
其中 epub是通過解析epub自身content.opt文件得到Book類對象的信息。
云閱讀epub解析器支持接入端解析(需要實現IMyNCXReader接口)。
(2)? Navpoint 為目錄toc或者章節spine的model類,包括章節id,url等信息
d、IParser解析器對外接口 (調用函數列表)
1、String createId(String path, String id);? 生成id
2、int getVersion();? ? 解析器版本
3、boolean canAcceptType(MimeType mime, MimeType subMime, String extType);? ? 解析器是否支持傳入的mime類型和擴展類型
4、boolean openBook(String path, String passWord, String id, boolean needReload, boolean needParserCover, boolean isPerfect);? 打開書籍,解析書籍信息、spine以及toc等
5、 void closeBook();? 關閉書籍,釋放資源
6、String getId();? 獲取唯一ID
7、int getChapterType();? 每個章是否需要獨立排版, txt等類型, 沒有明確的章概念, UI可能需要連續排版
8、PrisTextChapter getChapter(NavPoint point, String password, String targetCssName);? 獲取一章內容
9、Bitmap getImage(String imgRef, float width, float height, BitmapFactory.Options opts);? 根據圖片索引獲取圖片(不同parser對圖片的解碼可能存在差異)
10、Bitmap getOriginalImage(String imageRef);? 獲取原始圖片
11、Book getBookInfo();? 獲取書的信息(書名, 作者, 封面...)
12、List<NavPoint> getSpine();? 獲取書籍spine信息, 用于書的讀取索引, 如txt的分段索引, epub的opf
13、List<NavPoint> getToc();? 用于顯示的目錄, 如某些類型(txt)的自能斷章, epub的toc
14、void beginSearch(String key);? 搜索相關
15、TextSearchInfo SearchUp(); 搜索相關
16、TextSearchInfo SearchDown();? 搜索相關
17、void endSearch();
18、NavPoint getSpineNavPoint(int index);? 通過章節索引獲取spine的NavPoint節點
19、NavPoint getSpineNavPoint(String id);? 通過Spine的ID獲取spine的NavPoint節點(兼容老版本,數據庫沒有索引字段)
20、NavPoint getPreSpineNavPoint(int index);? 通過Spine索引獲取spine的前一個NavPoint節點
21、NavPoint getNextSpineNavPoint(int index);? 通過Spine索引獲取spine的下一個NavPoint節點
22、NavPoint getTocNavPoint(int index);? 通過toc索引獲取toc的NavPoint節點
23、NavPoint getTocNavPoint(String id);? 通過toc的ID獲取toc的NavPoint節點
24、int getChapterSize();? 獲取章節數量(表示書籍閱讀順序的spine節點數)
25、NavPoint getTocNavPointBySpine(NavPoint point, Object... obj);? 通過spine的NavPoint節點獲取對應的toc的NavPoint節點
26、NavPoint getSpineNavPointByToc(NavPoint point);? 通過toc的NavPoint節點獲取對應的spine的節點
27、String getUnfoldBookPath();
四、epub解析的原理:
解析章節內容有點類似于解析h5。一個章節內容的文件如下圖所示。
主要是關注里面的標簽,類似于h5 文件。
通過標簽對文件進行解析,解析成段落的集合。得到一個TextParagraph的list。
EpubParser解析器關健代碼:
ParserBase 是txt, umd, doc, epub解析器的基類(抽象類),繼承自IParser接口,實現了其中一些公共的方法。
其中比較重要的是openBook方法,具體的實現在各種子類的iniBook方法中。
EpubParser中通過OEBReader類讀取opf文件,獲取書籍信息和目錄等信息(類似xml解析)。
canAcceptType()方法能夠通過傳入參數判斷解析器是否支持當前類型。
getChapter()方法是根據目錄Navpoint獲取對應章節的對象,通過NEFile類讀取文件(類似xml解析)
ps. epub具體解析代碼見下圖中的類
五、sdk如何接入與基本使用
a、接入:
(1) 引入解析器aar文件
(2) 在app中進行初始化
(3) 接入端可以使用一個ManagerBookParser類進行統一管理
下圖為蝸牛的ManagerBookParser類,在Manager類中設置初始化任務(init方法)與緩存地址(CacheHelp),獲取解析器類型(getParser方法)。 其中getBaseRootExternalDir()為解析后文件存儲地址(內部存儲/data/data/packageName路徑),getBookChapterPath(String s, String s1)書籍文件所在地址。
云閱讀支持的類型更多(txt、epub等):
b、使用:
以蝸牛為例 , ReadbookNewActivity類中:
(1) 聲明
(2) 獲取解析器實例。
(3)? 調用解析器的openBook方法進行書籍解析。(必須)
(4) openBook完成后,可以調用getBookinfo()方法獲取到書籍信息(包含title、封面、作者、 目錄等)。
(5) 通過getToc() 方法可以獲取目錄list。
(6) getToc() 方法得到Navpoint的list集合(目錄)
(7) 、getchapter()方法可以通過傳入想獲取章節的目錄和密碼,得到解析后的章節實例prisTextChapter。(password只有云閱讀epub需要傳入,其他解析器傳入null或者“”即可)。
其中傳入參數為navpoint(可以根據id獲取對應章節navpoint)
getCatalog方法如下,通過id對比得到。
(8) 在ondestry中銷毀。
ps? ? 前面說了,云閱讀定制epub解析器除了支持解析epub中目錄,也可以由接入端進行解析, 必須實現ISrNCXReader接口,其中read()方法為獲取書籍的信息與目錄
可以看到BookParser中PrisOfOnlineEpubParser有兩個get方法,其中可以傳入參數,一個無參數。 (云閱讀調的第一個,蝸牛調的第二個。)
蝸牛傳入了SrNCXReader類的實例。
SrNCXReader實現了IMyNCXReader接口,read方法通過解析json方式實現了獲取書籍的信息與目錄。