4

私は98%の時間、100%自分のテストで動作するコードを持っているので、ユーザーデバイスにこの問題を経験させる以外に問題を実際に再現することはできません。

onPostExecute()で行うことは、次のようなパラメーターを設定することです。

   SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( AddProblemActivity.this);
            prefs.edit().putString("recent_problem_id", result ).commit();

次に、次のアクティビティに進みます。

            Intent myIntent = new Intent(AddProblemActivity.this, ProblemActivity.class);
            AddProblemActivity.this.startActivity(myIntent);

次に、次のようにそのパラメータを取得してみます。

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( 
              ProblemActivity.this);         

    // display a loading message before problem loads.
    String recent_problem_id = prefs.getString( "recent_problem_id" , null );

    if ( recent_problem_id == null )
    {
        // Sometimes it is null!            
    }

なぜこれが起こるのか誰かが知っていますか?

ありがとう!

4

7 に答える 7

5

データを新しいアクティビティに渡そうとしている場合、それをインテントに String エクストラとして入れてみませんか? 次に、新しいアクティビティのインテントからその文字列を取得します。それでも保存する必要がある場合は、インテントからプルした後、新しいアクティビティの onCreate() で保存できます。

Intent myIntent = new Intent(AddProblemActivity.this, ProblemActivity.class);
//Add results here
myIntent.putExtra("RecentProblemId", result);
AddProblemActivity.this.startActivity(myIntent);

次に、新しいアクティビティの onCreate で、次のようにします。

String recentProblemId = getIntent().getStringExtra("RecentProblemId");

この情報を保存する必要がある場合は、次のようにします。

if(recentProblemId != null){
    SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences( 
              ProblemActivity.this);         
    prefs.putString("recent_problem_id",recentProblemId).commit();
}

String が onPostExecute() の設定に常にコミットされていない理由について、これがあなたの質問に正確に答えていないことはわかっています。ただし、アクティビティ間で情報を渡すためのベスト プラクティスは、インテントとエクストラを使用することです。

一部のユーザーにとって常に機能するとは限らない理由についての私の推測は、新しいアクティビティが開始されて同じファイルから読み取ろうとする前に、デバイスが共有設定ファイルへのデータの書き込みを完了していないことです。お役に立てれば。

于 2012-10-01T20:52:36.320 に答える
2

まず、Raghav Sood の回答を参照してください。
微妙な瞬間があります。デバイスをローテーションするよりも、AsyncTask の実行を開始する場合があります。アクティビティが再作成され、PostExecute ではコンテキストが間違っているため、設定が保存されません。
true の場合は、onRetainNonConfigurationInstance() を使用して、適切なタスクのインスタンスを保存する必要があります。

于 2012-10-02T09:09:56.550 に答える
1

この問題は、2番目のアクティビティからファイルシステムにアクセスしようとしたときに、共有設定がまだファイルシステムに書き込まれていないことが原因だと思います。onPostExecuteあなたはあなたがメソッドから設定を書くと言います(AsyncTaskおそらく?)。あなたが始めるときAsyncTask、それがすぐに始まるという保証はありません。唯一の保証は、バックグラウンドスレッドで開始されることです。プラットフォームは、システムの負荷やファイルシステムのブロックなどに応じて、バックグラウンドスレッドを実際に実行するタイミングを決定できます。AsyncTask2番目のアクティビティに切り替えたときに、まだ開始されていない可能性があります(したがって、onPostExecuteメソッドはまだ呼び出されていません)。

共有設定を保存することは、ファイルシステムに書き込むときに注意が必要です。注意しないと、メインスレッドをブロックしてしまう可能性があります。SharedPreferences.Editorオブジェクトには、共有設定のメモリ内キャッシュをすぐに更新し(変更を一度に利用可能にする)、バックグラウンドスレッドを開始して実際の値をファイルシステムに保存するメソッドapplyもあります。したがって、私のヒントは、可能性がある場合は、(私が想定している)からapplyのメソッドではなく、(メインスレッドから)メソッドを呼び出そうとする必要があるということです。このメソッドには、APIレベル9以上が必要です。commitAsyncTaskapply

参考までに:http://developer.android.com/reference/android/content/SharedPreferences.Editor.html

編集:

このcommitメソッドは、書き込み操作の結果に応じてブール値を返します。少なくとも失敗時に正しい対策を講じることができるように、その戻り値を確認することができます(すべきですか?)(「設定を保存できませんでした。もう一度やり直してください」トーストなどを表示するなど)。

乾杯、-dbm

于 2012-10-01T12:26:57.527 に答える
1

これについてはよくわかりませんが、渡すコンテキストの違いが原因である可能性があると思います。AddProblemActivity最初にの Context を使用し、次に の Context を使用していますProblemActivity。ファイル名のような設定を使用してみてください:

SharedPreferences prefs = getSharedPreferences("MyPrefs", Context.MODE_PRIVATE);

getSharedPreferences ()は Context のメソッドであるため、AsyncTask で使用できるようにするには、Activity または Application Context への参照が必要になることに注意してください。

于 2012-09-26T15:33:00.643 に答える
1

あなたのコードは問題ないようで、動作しない理由はありません。唯一の理由は、おそらくデバイスに関連する何らかの欠陥です。私の考えでは、共有設定はローカル ストレージに保存されるため、その過程で何か問題が発生する可能性があります。

コメントでアドバイスされているように、デバイス タイプのログを追加する必要があります。「ACRA」を使用することをお勧めします - http://code.google.com/p/acra/最小限の労力で詳細なレポートを取得できます(必ずしもアプリのクラッシュだけでなく、レポートを送信できることに注意してください)。

このスレッドを見てください。彼は、おそらくあなたも経験している問題を示しています: SharedPreferences は PreferenceActivity に保存/ロードされません。その場合、解決策は、この永続データのローカル ストレージへの保存を手動で処理するか、DB ソリューションを使用することです。幸運を :)

于 2012-09-29T20:01:46.420 に答える
0

SharePreferencesのコミットアクションは同期であるため、新しいインテントを開始しているという事実がそれに影響を与えるとは思わない。唯一のことは、コミットアクションがフェイルセーフではなく、失敗する可能性があるということです。

http://developer.android.com/reference/android/content/SharedPreferences.Editor.html#commit()

新しい値が永続ストレージに正常に書き込まれた場合はtrueを返します。

たぶん、その戻り値をチェックして、結果を保存できたことを確認する必要があります。

于 2012-10-06T07:53:39.287 に答える
0

私は間違っているかもしれません。しかし、私の友人がかつて同様の問題を抱えていたと思います。私はこの問題に何時間も悩まされていました。結果は、30% 以上の確率でうまくいきませんでした。インテントがインスタンス化され、アクティビティが呼び出されると、 onPostExecute() は別のスレッドで実行されると思います。これは、AsyncTask が別のスレッドに実装されているためです。デバイスによっては、これが呼び出される可能性が高くなります。私たちのタブレットではめったに発生しませんでしたが、スマートフォンではより一般的に発生しました。

これをテストするには、アプリケーションをデバッグし、AsyncThread スレッドを見て、いつ呼び出しが行われたかを確認します。

はい、putExtra() を介して変数を送信することをお勧めします。

なぜこれが起こったのかを理解するのに役立つことを願っています。

于 2012-10-04T20:17:41.647 に答える