I am creating an Android app that needs to access the Bible. I want it to be offline, so I prefer not to use one of the internet APIs. After reading this this post, I decided to store the text locally as XML, like this
<bible>
<b n="Genesis">
<c n="1">
<v n="1">In the beginning, God created the heavens and the earth.</v>
My problem is that the file is almost 34,000 lines long (4.4 MB) and it takes a LONG time (a few minutes) to parse the entire text.
Right now I’m using the XmlPullParser, like this
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
XmlPullParser xpp = factory.newPullParser();
InputStream iStream = getResources().openRawResource(R.raw.bible);
BufferedReader reader = new BufferedReader(new InputStreamReader(iStream));
xpp.setInput(reader);
int eventType = xpp.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT)
{
// do something here
eventType = xpp.next();
}
Is there a better way to store and/or access the bible locally on Android?
I’ve considered storing it as multiple XML files to parse it faster (a separate file for each book) but would prefer not to if possible.
I am open to any suggestions, including storing the text as something other than XML.
Thanks
I would just use SQLite as a “starting place” – that is, why not? (Well, really, an existing library / book reader / well established file schema would even better, but barring that 🙂
SQLite has very efficient “on disk” access – e.g. no need to “parse” to memory or read an entire file – and it supports efficient seeks over indices (e.g. looking up a specific verse or getting chapters 2 through 12 in Exodus). I would expect both the SQLite database and the original XML file to have a comparable file size (assuming the XML is UTF-8 encoded).
Then make a program/function to “load” the XML into the appropriate schema in the SQLite database – this can be done ahead of time (e.g. on a PC and then distribute the pre-populate SQLite database files) or the first time said XML is loaded on the client. This can be effectively the same reading code as it is now .. just replace “do something” with “update database”.
I would avoid a splitting-of-files approach unless there is a particularly good reason for it – it will make it faster to find a specific chapter/verse, but it doesn’t really “solve the problem”. Since it’s using a sequential reader and not a full DOM it won’t necessarily result in less memory – it will just limit the garbage “read over” (and then discarded) while seeking. But then again, why not SQLite?