2

Android 用のハングマン アプリを作成していますが、読み込みの問題が発生します。アプリの起動時に、txt ファイルからランダムな単語を選択して生成します。問題は、このファイルが重いことです。ほぼ 360,000 語 (4000 kB) あるため、1 つの単語を選択するのに 10 秒から 20 秒かかります。ファイルを読み、毎回単語を選択するためです。 [生成] をクリックします。

アプリが起動したらファイルを読み取り、その内容を文字列配列に入れるとよいでしょうか? 配列がこれだけ処理できるかどうかはよくわかりません。そうでなければ、どのパターンが良いでしょうか?

読んでくれてありがとう。

4

6 に答える 6

1

CSV (カンマ区切り値) として保存します。読み取りストリームを開き、ランダムな位置を探して、','2 回ヒットするまで文字の小さなチャンクを読み取ります。次に、読み取った文字列からコンマの間の単語を抽出します。また、「#」や「|」などのカスタム区切り文字を使用することもできます コンマの代わりに。

更新: を使用しRandomAccessFileます。

Update2: readLine()1 行に 1 単語を保存すると、これがさらに簡単になります。つまり、\n

于 2012-11-27T11:26:04.917 に答える
0

ここで注意すべき点がいくつかあります。

  1. アプリがSDカードから読み取る場合、SDカードの品質が実際に要因になります-使用しているSDカードのクラスに応じて読み取り/書き込み速度が異なります-調べてください。

  2. [生成]をクリックするたびにファイル内のランダムな行を選択するとおっしゃいましたが、ユーザーは[生成]を複数回クリックすることが確実なので、そのファイルを1回読み取り、内容をどこかに保存することをお勧めします( sqlite)、次にランダムな単語を取得する必要がある場合は、保存されているデータから取得します。このようにして、外部ストレージ(モバイル標準では重いタスク)から読み取る回数を、アプリケーションの起動ごとに1回に制限します。

  3. ファイルにマーカーを配置して、内容が変更されたかどうかを通知することもできます。ランダムな文字列から現在の日付、md5チェックサムまで、ファイルを再度読み取る必要がないことを通知する必要があります。これは、ファイルを以前に読み取り、その内容をsqliteデータベースに保存しているためです。これをファイルの最初の行に配置します。

  4. 他のみんながsqlitedbに書き込むか、.dbファイル自体(個別に生成できます)をコピーすることを検討するように言っているので、ランダムなアイテムを選ぶのは簡単です。データベースに360,000エントリを書き込むことについて警告したいと思います。デフォルトのContentProviderinsert(Uri, ContentValues)メソッドを使用しても機能しますが、実際にファイル自体を解析するよりも時間がかかっても驚かないでしょう。ここでの秘訣は、bulkInsert(Uri, ContentValues[])代わりにコンパイルされたステートメントを使用して、ContentProviderの実装をオーバーライドすることです。デフォルトの実装では、insertメソッドが複数回呼び出されるだけなので、挿入のたびにSqliteDatabaseオブジェクトを開いたり閉じたりします。あなたがしたいのは、一番上で呼び出し、ContentValuesの各項目をsbeginTransactionするforループを持って、それからを呼び出すことです。insertsetTransactionSuccessfulendTransaction

于 2012-11-27T12:03:47.493 に答える
0

単語のデータベースを作成し、ランダムな単語をクエリすることができます (おそらく最善の方法です)。SQL データベースでのデータの保存を読むことから始めることができます

于 2012-11-27T11:17:40.527 に答える
0

ファイル全体を文字列配列に読み込むことは、多くのメモリを消費するため、良い戦略ではありません。簡単な解決策の 1 つは、大きなファイルを複数の単一ファイルに分割することです (words1.txt、words2.txt などのファイル名のパターンを使用)。単語を描画するときは、最初にファイルを選択し、次にファイルから実際の単語を選択します。

于 2012-11-27T11:18:43.633 に答える
0

ファイルの読み取りはコストのかかる操作であり、それだけの時間がかかるのは普通のことです。おそらく、1 つのファイルではなくファイルのグループを作成する必要があり、アプリを起動するたびに、そこからランダムなファイルとランダムな単語を選択できます。これにより、所要時間が短縮されるはずです。

また、 /res/values/ フォルダーに入る App リソースとして XML ファイルに単語名を保存することもできます。ファイルのオープン/クローズ/読み取りを気にすることなく、文字列配列リソースを作成してコードから簡単に取得できます。それはかなり簡単です。ただし、ここでも、すべての単語を異なる xml ファイル (または少なくとも文字列配列グループ) に分割することが重要です。詳しくはこちらをご覧ください。http://developer.android.com/guide/topics/resources/string-resource.html#StringArray

または、ファイルからすべてを読み取って DB に保存することもできます。このように、アプリの最初の起動にのみ時間がかかります。作業中に「DB を準備しています...」などのメッセージを表示できます。

于 2012-11-27T11:20:01.900 に答える
0

コードを実行して、AsyncTask でコンテンツ フォーム json/db を解析/ロードすると、速度が向上します。行あたり〜400文字で5000行をロードします。AsyncTask がないと、はるかに時間がかかります。

    private class YourTask extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... s) {

            //Here you have to make the loading / parsing tasks
            //Don't call any UI actions here. For example a Toast.show() this will couse Exceptions
            // UI stuff you have to make in onPostExecute method

        }

        @Override
        protected void onPreExecute() {
            // This method will called during doInBackground is in process
            // Here you can for example show a ProgressDialog
        }

        @Override
        protected void onPostExecute(Long result) {
            // onPostExecute is called when doInBackground finished
            // Here you can for example fill your Listview with the content loaded in doInBackground method

        }

}

実行するには、次のように呼び出すだけです。

new YourTask().execute("");

AsyncTasks の詳細については、次を参照してください。

AsyncTask 開発者ガイド

于 2012-11-27T11:24:38.227 に答える