18

http://developer.android.com/guide/components/loaders.htmlにあるローダーの Android ドキュメントには、ローダーのプロパティの 1 つが次のように記載されています。

構成の変更後に再作成されると、最後のローダーのカーソルに自動的に再接続します。したがって、データを再クエリする必要はありません。

次のコードはその動作を反映していないようです。新しいローダーが作成され、ContentResolver のクエリが終了し、画面が回転してローダーが再作成されます。

public class ReportFragment extends Fragment implements LoaderCallbacks<Cursor> {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getLoaderManager().initLoader(1, null, this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment_report, container, false);
        return v;
    }

    public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
        Log.d("TEST", "Creating loader");
        return new CursorLoader(getActivity(), ResourcesContract.Reports.CONTENT_URI, null, null, null, null);
    }

    public void onLoadFinished(Loader<Cursor> arg0, Cursor arg1) {
        Log.d("TEST", "Load finished");
    }

    public void onLoaderReset(Loader<Cursor> arg0) {

    }

}

私のlogcatからの出力は次のとおりです。

08-17 16:49:54.474: D/TEST(1833): Creating loader
08-17 16:49:55.074: D/TEST(1833): Load finished
*Here I rotate the screen*
08-17 16:50:38.115: D/TEST(1833): Creating loader
08-17 16:50:38.353: D/TEST(1833): Load finished

ここで何が間違っているのか分かりますか?

編集:

私は Android Google API のバージョン 8 をビルドしており、v4 サポート ライブラリを使用していることに注意してください。

2回目の編集:

これは、サポート ライブラリのバグが原因である可能性が最も高いです。詳細情報が必要な場合は、このバグの送信をご覧ください。

http://code.google.com/p/android/issues/detail?id=20791&can=5&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

4

6 に答える 6

1

私の意見では、ドキュメントの内容を誤解しています。ドキュメントには、データを再クエリする必要はないと書かれていますが、そうしていません。

メソッドにブレークポイントを記録/挿入してみてくださいContentProvider#query()! クエリは、向きの変更後ではなく、アクティビティの起動時にのみ呼び出されます。

LoaderCallbacks#onCreateLoader()しかし、これはメソッドには当てはまりません。向きが変わるたびに呼び出されますが、これは再クエリを意味するものではなく、メソッドを呼び出すだけなので、必要に応じて CursorLoader を変更できます。

于 2017-09-09T16:29:15.417 に答える
0

これは少し古い質問ですが、ここで私の見解を述べたいと思います。

onSaveInstanceState に追加情報を保存する必要はありません

フレームワークは、構成の変更後に再作成されるときに、最後のローダーのカーソルに自動的に再接続します。したがって、データを再クエリする必要はありません。

つまり、onCreate 関数では、savedInstanceState が null の場合にのみ loaderManager を呼び出す必要があります。

元:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(savedInstanceState == null) {
        getLoaderManager().initLoader(1, null, this);
    }
}
于 2016-10-04T08:08:25.257 に答える
-1

ローダーがonCreateにすでに存在するかどうかを確認するだけです。次に、初期化または再起動できます。

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getLoaderManager().getLoader(LOADER_ID) == null) {
        getLoaderManager().initLoader(LOADER_ID, null, this);
    } else {
        getLoaderManager().restartLoader(LOADER_ID);
    }
}

通常、IDをローダーに渡すので、後でローダーマネージャーを介してIDを参照できます。

お役に立てれば!

于 2012-08-17T18:50:52.513 に答える
-3

アクティビティが破棄されて再作成されるため、画面の向きの変更中に onCreate() が呼び出されます。

大量のデータをロードしていない限り、問題はありませんが、必要に応じて次のことを試すことができます (私はテストしていませんが、理論的にはうまくいくと思います)。

クラスの最上位グローバルで静的ブール値を宣言します。参照する静的カーソルも必要になると思います

private static boolean dataDownloaded = false;
private static Cursor oldCursor;

次に、onLoadFinished で dataDownloaded = true を設定します

onSaveInstanceState をオーバーライドしてブール値を保存する

@Override
protected void onSaveInstanceState(Bundle outSave) {
    outSave.putBoolen("datadownloaded", dataDownloaded);
    oldCursor = adapter.swapCursor(null);
}

および onCreate に以下を追加します

if (savedInstanceState != null) {
    this.dataDownloaded = savedInstanceState.getBoolean("datadownloaded", false);
}

onCreateLoader を調整します

public Loader<Cursor> onCreateLoader(int id, Bundle args) {
    CursorLoader cursorLoader;
    if (dataDownloaded) {
        cursorLoader = new CursorLoader(getActivity(),
            null, projection, null, null, null);
        cursorLoader.deliverResult(oldCursor);
    } else {
        CursorLoader cursorLoader = new CursorLoader(getActivity(),
            URI_PATH, projection, null, null, null);
    }

    return cursorLoader;
}
于 2012-08-17T18:30:30.650 に答える