17

Androidでファイルを保存するときにデータの損失を回避するために他の人がどのような戦略を使用しているのか疑問に思っています。私はいくつかのゲームアプリを持っており、基本的に、ユーザーが一時停止(onPause)するたびにゲームの状態/セーブゲームを保存する可能性があります。

これは99.99%のケースで機能しますが、保存プロセスが失敗したセーブゲームの例を時々受け取ります。通常、これは不正な形式のXMLファイルであり、通常、任意の時点で切り捨てられます。私が受け取ったバグレポートに基づくと、問題は主に、ゲームプレイ中に電話などによってユーザーが中断され、AndroidOSが保存を完了する前にアプリを強制終了した場合に発生すると考えられます。ファイルを保存するためのコードは非常に単純なので、他に何がこの問題を引き起こす可能性があるのか​​を理解するのは困難です。

これは深刻な問題です。通常、プレーヤーの保存の進行状況が台無しになるためです。

最初に空のファイルに書き込み、その後で「実際の」ファイルにコピーすることを考えていましたが、全体的に時間がかかり、中断されるリスクがあるため、問題が増えるだけだと思います。

これを行うための安全な方法を持っている人は、Androidが混乱しないことが比較的保証されていますか?


要約すると、これまでに提案されたオプション(私が理解しているように):

  1. OSによって強制終了される可能性が低いと想定して、保存プロセスにサービスを使用します。
  2. 一時ファイルに保存します。保存が確認されたらコピーします。
  3. ゲーム状態の増分保存(実際には、これをプレーヤーのログ情報にすでに使用しています)。
  4. 2と3の組み合わせ。
  5. 問題はANRの強制終了にある可能性があるため、保存を別のスレッドに移動します[以下のDCのコメント]。

SharedPreferencesがこの種の構造化データに対して機能するとは思いません。現時点では、これらの方法はどちらも理想的なソリューションとは思えないため、まだ提案を受け付けています。


私はまだこれらすべてのアプローチをテストすることができていないので、賞金を無駄にするのではなく、問題を解決する可能性が最も高いと思う答えに割り当てました。ただし、回答を受け入れる前に、さまざまなオプションを確認する予定です。良い提案をありがとう。

4

5 に答える 5

4

これはサービスにとって良い仕事のように思えます。

http://developer.android.com/reference/android/app/Service.html

于 2012-04-20T19:03:37.420 に答える
4

メインスレッドから永続ストレージ(内部メモリ上のプライベートファイルシステム)へのI / O(通常は書き込み)を実行しているときに、問題が発生することがあります。通常、これにはそれほど時間はかかりませんが、場合によっては、説明のつかないほどの時間がかかります(20秒または30秒以上)。一部のデバイスでのAndroidファイルシステムの実装は同時アクセスをサポートしていないようです(これを参照してください。別のプロセスがファイルシステムを使用している場合、I/Oがブロックされる可能性があります。メインスレッドであるOSでI/Oを実行している場合アクティビティが長時間ブロックされると、アクティビティを強制終了できます/強制終了します。これがあなたに起こっていることかもしれません。

この問題のため、すべてのI / Oを別のスレッド(メインスレッドではない)に移動することをお勧めします。したがって、たとえば、ゲームの状態を保存するには、onPause()で、ゲームの状態をByteArrayOutputStreamにシリアル化するメソッドを呼び出し、それを別のスレッドに渡して、最終的にファイルシステムに書き込みます。

于 2012-05-09T11:05:39.537 に答える
2

この場合、ユーザーがアクションを実行するたびに(onPause()呼び出されたときだけでなく)、データのごく一部(ゲームの状態全体ではない)をデータベースに保存するのが最善の方法だと思います。ただし、これにはコードに多くの変更が必要になる場合があります。

妥協案は、ゲームの状態を小さな部分またはサブ状態(たとえば、、、 ...、など)に分割し、round1ユーザーround2が呼び出しplayersを待たずにアクションを実行するときに、データを適切なファイルに再度保存することです。onPause()これにより、損失の可能性が大幅に減少し、少なくともユーザーがゲームの進行全体を失うことがないことが保証されます。さらに、保存プロセスが中断されたときに表示される可能性のあるアプリの一貫性のない状態を回避するには、最初にデータを一時ファイルに保存し、成功した場合にのみ、コンテンツをコピーせずにファイルの名前を変更することをお勧めします(たとえば、round1.xml.tmp名前を変更します)。にround1.xml)。

于 2012-05-05T08:17:34.150 に答える
1

まず最初に、アプリが本当に通知なしに強制終了されるかどうかを確認しようとします。そうすべきではないと思うからです。電話のような理由でアプリが停止する可能性がありますが、Androidが通知なしにアプリを強制終了しているとは思いません。それを終了することを決定することはできますが、状態などを保存せずに終了することはできません。

たぶん、保存自体で発生するエラーだけがあります。

チェックサムを使用するか、保存されたデータの整合性を検証するために他の方法(サイズ、終了マーカーなど)を使用することで、チェックに多くの変更を必要としない方法。あなたがしなければならないのはそれを保存し、それを読んでそれをチェックし(間違いを記録し)そしてそれが正しくなるまでそれを繰り返すことです。大量のデータを保存する場合はそれほど良くないかもしれませんが、単なるゲームデータの場合は問題ありません。

また、アプリの起動時と終了時の状態を設定すると、次回の起動時に前回正しく終了したかどうか、追加の対策が必要かどうかがわかります。

于 2012-05-06T14:27:19.847 に答える
0

可能であればSharedPreferences、ゲームの状態を保存するために使用します。変更は、に電話した後にのみコミットされますcommit()。コールバックで保存できonSaveInstanceStateます。こちらのドキュメントをお読みください。

于 2012-05-06T14:06:25.270 に答える