8

使用時に少しトラブルに見舞われAsyncTaskLoader、画面の向きが変わります。私のアプリがどのように構成されているかについて、いくつかのコンテキストを説明しましょう。URLから結果を取得して表示する、非常にシンプルなアプリがあります。アプリは1つとFragmentActivity3つで構成されていFragmentsます。私の3つのフラグメントは次のとおりです。

  • 最初のフラグメントは、編集テキストと入力を送信するためのボタンです。
  • 2番目のフラグメントはローディングスピナーを示しています
  • 3番目のフラグメントは、結果を表示するためにデータがフェッチされるときに、loadingフラグメントを置き換えます。

AsyncTaskLoader、コンテンツプロバイダー(キャッシュされている場合)またはネットワークからデータをロードするために使用されます。

画面の構成が変わるまで、すべてがうまく機能します。の出力を確認しましたLoaderManager.enableDebugLogging(true) が、問題の原因はLoaderCallbacks.onLoadFinished、アクティビティで呼び出されないことであるようです。

ローダーを起動するコードの一部を次に示します。

/* This function is defined in the "first" fragment in an interface and
 * implemented in the activity */ 
@Override
public void onFormSubmission(String word) {                     

    showLoadingFragment();

    if ( mWord == null || mWord.equals(word) ) {
        getSupportLoaderManager().initLoader(0, word, this);
    } else {
        getSupportLoaderManager().restartLoader(0, word, this);
    }

    // Store the word
    mWord = word;
}

結果を表示するコード:

@Override
public void onLoadFinished(Loader<Bundle> loader, Bundle data) {
    // Validation and other stuff

      ResultFragment fragment = new ResultFragment();

      // Add the fragment to the 'result_fragment_container' FrameLayout
      getSupportFragmentManager()
            .beginTransaction()
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
            .setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out)
            // Replace loading fragment with the result
            .replace(R.id.result_fragment_container, fragment)
            .commitAllowingStateLoss(); 
}

私が試したが失敗したアプローチ:

  • setRetaininstance(true)フラグメントで設定します。
  • android:configChanges="orientation|keyboardHidden|keyboard"マニフェストに設定します。

私はアイデアがないので、助けていただければ幸いです。

4

2 に答える 2

1

メソッドを入力する必要がgetSupportLoaderManager().initLoader(0, null, this);ありonActivityCreated ます。initLoaderは、ローダーがすでに存在する場合、ローダーを作成するか、ローダーと再接続します

于 2013-03-05T23:55:42.400 に答える
1

こんにちは私は2つの可能な解決策を提案することができます:

1)あなたの質問から、AsyncTaskでOnLoadFinished()を呼び出さないプロセスを実行しているのか完全にはわかりません。AsyncDB呼び出しやWebサーバー呼び出しなどだと思いますか?

関係なく、アクティビティはローテーションで破棄されるため、onLoadFinished()はおそらく呼び出されません。ローテーションの前に更新した状態を保存する必要がありonDestroy()

クラス変数ステータスフラグを保持してみることができます。これは、タスクがまだ実行中であるかどうか、つまり「更新中」であるかどうかを示す「更新」Asyncタスクで設定されます。Async

それで:

  • bUpdating = true更新asyncタスクの開始時。つまり、 onPreExecute()
  • bUpdating = falseそれが終わったとき。つまり、 onPostExecute()

次に、 onDestroy()が呼び出されたとき(常に画面が回転する前に呼び出されます)を確認できますbUpdating。次に、タスクでIF TRUE保存されたはずのすべての詳細を画面に保存できます。AsyncSharePreferences

特定の変数をonResume()確認SharePreferencesし、それらが存在する場合は、Async更新を再度開始します。

つまり、これは次のようになります。

  • 画面を回転するSharedPreferences に詳細を保存しonDestroy()ます---ブール値が非同期タスクの実行を示している場合。
  • onResume() 画面の回転後、を使用SharedPreferencesして詳細を確認および保存しAsyncます。
  • onLoadFinished()これに続いて、メソッドが呼び出されることが保証されます。

画面の回転をチェックするためのより信頼性の高い方法もおそらくありますが、私はそれをあまり使っていません。

2)もちろん、別の方法は、特定のアクティビティで画面の回転を完全にブロックすることです(実際、その画面で回転が必要なためですか?)。

ビデオをバックグラウンドで録画し、10秒のセグメントをアップロードするアプリケーションがあります。画面の回転と非同期タスクで大きな頭痛の種を引き起こしていたので、完全に不要だったので回転を完全にブロックしました。画面の向きを縦向きにロックするAndroidManifest.xmlファイルのコードは次のとおりです。

     <activity 
        android:name="com.blah.YourActivity"
        android:label="Register"
        android:screenOrientation="portrait">
    </activity>

それがあなたを助けることができることを願っています

編集:また、画面が回転していることを知るためのより明確な方法である可能性があります:

つまり、この種のコード:

public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Log.e(TAG, "ORIENTATION_LANDSCAPE");
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
        Log.e(TAG, "ORIENTATION_PORTRAIT");
    }
}

この投稿からの例

SharePreferencesそこにセーブを入れることができます。ただし、onResume()は、詳細を取得するために引き続き使用されます。

また、これまで使用したことがない場合のリンクSharePreferences

Edit2!:もう1つ。私はあなたの質問を読み直しました、そしてあなたはなぜか私が頭の中にそれを持っていた「ローダー」について言及しました、これはロードではなくデータを保存していました。AsyncTaskLoader()onResume()が呼び出されたときに単純に再呼び出ししてみましたか?SharePreferences保存しない場合は、onResume()(ローテーション後に実行)で非同期ロードタスクを再度開始できるため、データの保持について私が言ったことをすべて無視できます。

于 2013-03-06T02:21:32.647 に答える