7

聖書にアクセスする必要がある Android アプリを作成しています。オフラインにしたいので、インターネット API のいずれかを使用したくないのです。この投稿を読んだ後、このようにテキストを XML としてローカルに保存することにしました。

<bible>
<b n="Genesis">
<c n="1">
<v n="1">In the beginning, God created the heavens and the earth.</v>

私の問題は、ファイルの長さがほぼ 34,000 行 (4.4 MB) あり、テキスト全体を解析するのに長い時間 (数分) かかることです。

今、私はこのように XmlPullParser を使用しています

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();
}

Android で聖書をローカルに保存および/またはアクセスするためのより良い方法はありますか?

より高速に解析するために複数の XML ファイルとして保存することを検討しましたが (書籍ごとに個別のファイル)、可能であれば保存したくありません。

テキストを XML 以外のものとして保存することを含め、あらゆる提案を受け入れます。

ありがとう

4

3 に答える 3

5

-まず、を使用して解析します。または、のような素晴らしいライブラリを試すことができます。XMLSAX, DOM, or Pull ParserJAXP and JAXB or the infamous Castor

-次に、聖書をデータベースにローカルに保存できSQLiteます。SQLiteはサーバーを含まない単一のファイルであるため、非常に高速に動作します。サイズは250Kまで小さくすることができます。

///////////////////編集された部分///////////////////////////// //

--UIスレッドでUIを動作させ、非UIスレッドで非UIを動作させ続ける方が常に優れていますが、Androidのバージョンが登場するとそれが法律になりました。HONEYCOMB

-したがって、を使用するか、Androidが提供するPainLessThreadingThread along with Handlerとして知られるより簡単なオプションを使用することを選択できます。AsyncTask

-上記を使用すると、バックグラウンドでプロセッサの重い作業を行っている間、UI 応答性が維持されます。

于 2012-10-26T05:27:46.200 に答える
3

SQLiteを「出発点」として使用するだけです。(まあ、実際には、既存の図書館/書籍リーダー/十分に確立されたファイルスキーマがあればさらに良いでしょうが、それを除けば:-)

SQLite は非常に効率的な「ディスク上」アクセスを備えています。たとえば、メモリに「解析」したり、ファイル全体を読み取ったりする必要はありません。また、インデックスの効率的なシークをサポートします (たとえば、特定の詩を検索したり、Exodus の第 2 章から第 12 章を取得したりします)。私は、SQLite データベースと元の XML ファイルの両方が同等のファイル サイズを持つことを期待しています (XML が UTF-8 でエンコードされていると仮定します)。

次に、XML を SQLite データベースの適切なスキーマに「ロード」するプログラム/機能を作成します。クライアントにロードされます。これは事実上、現在と同じ読み取りコードになる可能性があります..「何かをする」を「データベースを更新する」に置き換えるだけです。

特に正当な理由がない限り、ファイルの分割アプローチは避けます。特定の章/詩を見つけるのが速くなりますが、実際には「問題を解決」しません。完全な DOM ではなくシーケンシャル リーダーを使用しているため、必ずしもメモリが少なくなるわけではありません。シーク中に「読み取り」(そして破棄) されるガベージを制限するだけです。しかし、もう一度言いますが、なぜSQLite を使わないのでしょうか?

于 2012-10-26T05:14:34.923 に答える
1

私のアドバイスは、XML 以外のものを使用することです。私は一般的に XML に対して何も持っていないことに注意してください。XML は何の役にも立たないと感じている人がかなりいるので、はっきりさせておきたいと思います。

この場合に XML を使用すると予想される結果の一部を次に示します。

ルックアップ時間

テキスト内の特定の位置にジャンプすると、常にコストがかかります。XML は、それを行うための 2 つの方法を提供します。

  1. 探していたフラグメントに到達するまで、ドキュメント全体をストリーミング方式で読み取ります。非常に遅い。
  2. ドキュメント全体をメモリ内データ構造に読み込みます。これにより、ある種の場所識別子から実際のテキスト フラグメントへのメモリ内インデックスを作成できます。メモリ消費の点で非常に高価です。

コンパクトさ

聖書全体を XML ファイルに変換すると、巨大になります。もちろん、Fast InfosetEfficient XML (どちらも XMLの背後にあるデータ モデルであるInfosetのバイナリ エンコーディング)などのソリューションがあります。少しは役に立ちますが、あまり役に立たないかもしれません。Gzipはおそらく約に減少します。元のサイズの 1/3 で、これも役に立ちますが、それでも大きいです。

代わりに何をしますか?

私のアドバイスは、聖書本文のバイナリ エンコーディングを検討することです。高速検索用に最適化されたもの。同様に、ファイル内にインデックスを持ち、その場所 (詩) をその実際のテキスト フラグメントが始まるオフセットにマッピングします。そして、それを適切に行えば、XML よりもはるかにコンパクトなものが得られるというボーナスさえあります。

もっと強く?

難しく聞こえるかもしれませんが、実際にはそうではないかもしれません。Preon は Android でも使用されており、メモリ内のデータ構造をバイナリ エンコードされた表現に宣言的にマップできるため、 Preon を検討することも検討してください。フレームワーク自体は、入力ファイルからデータを遅延ロードする機会があるかどうかを判断します。

于 2012-10-26T06:39:29.223 に答える