63

Androidにローダーの例を実装しようとしていますが、ローダーを起動させることができません。私は次のコードを使用しています。「ローダーの作成」にヒットしますが、「ロード開始」ログメッセージには到達しません。必要な電話がありませんか?

アクティビティ:

    public class TestingZoneActivity extends ListActivity implements LoaderCallbacks<ArrayList<Content>>{

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            getLoaderManager().initLoader(0, null, this);
        }

        @Override
        public Loader<ArrayList<Content>> onCreateLoader(int id, Bundle args) {
            Log.e("TEST", "Create Loader");
            return new ImageLoader(this);
        }

        @Override
        public void onLoadFinished(Loader<ArrayList<Content>> loader, ArrayList<Content> data) {
            setListAdapter(new ImageAdapter(this, data));
        }

        @Override
        public void onLoaderReset(Loader<ArrayList<Content>> loader) {
            setListAdapter(null);
        }
    }

ローダ:

    public class ImageLoader extends AsyncTaskLoader<ArrayList<Content>> {

        public ImageLoader(Context context) {
            super(context);
        }

        @Override
        public ArrayList<Content> loadInBackground() {
            Log.e("TEST", "Loading started");
        }

    }
4

6 に答える 6

131

互換性ライブラリを使用しても同じ問題が発生しました。電話で解決しましたforceLoad

getLoaderManager().initLoader(0, null, this).forceLoad();

明らかに、AsyncLoaderのドキュメントが不足しており、この問題はHoneyCombにも存在します。詳細については、こちらをご覧ください

AsyncTaskLoaderの公式のもforceLoad()を呼び出しているので、バグではありませんが、それでもその動作はあまり直感的ではないと思います。

于 2012-05-10T15:30:51.920 に答える
14

raystのアドバイスは非常にコンパクトです。メソッドを次のように記述すると、次のようになります。

protected void onStartLoading() {
    forceLoad();
}

onStartLoading子アクティビティが表示されてから親アクティビティに戻ると、 (などloadInBackground) が再度呼び出されることに気付くでしょう。

あなたは何ができますか?コンストラクター内で内部変数 ( mContentChanged) を true に設定します。次に、この変数を 内でチェックしますonStartLoading。true の場合のみ、実際に読み込みを開始します。

package example.util;

import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;

public abstract class ATLoader<D> extends AsyncTaskLoader<D> {

    public ATLoader(Context context) {
        super(context);
        // run only once
        onContentChanged();
    }

    @Override
    protected void onStartLoading() {
        // That's how we start every AsyncTaskLoader...
        // -  code snippet from  android.content.CursorLoader  (method  onStartLoading)
        if (takeContentChanged()) {
            forceLoad();
        }
    }

    @Override
    protected void onStopLoading() {
        cancelLoad();
    }
}
于 2013-10-20T18:36:26.893 に答える
3

ここでの回答(受け入れられたものを除く)だけではこれを解決するのに役立たなかったので、これが私にとってどのように機能したかです。

受け入れられた答えは正しい解決策ではないと思いますloadInBackground()。これは、ローダで次のメソッドを適切にオーバーライドしても発生しない方向の変更など、必要以上に頻繁に呼び出されるためです。

@Override
public void deliverResult(final List<Participant> data) {
    participants = data;

    if (isStarted()) {
        super.deliverResult(data);
    }

}

@Override
protected void onStartLoading() {
    if (takeContentChanged() || participants == null) {
        forceLoad();
    }
}
于 2015-09-02T15:12:06.573 に答える
0

上記の各解決策には問題があることがわかりました。特に、画面がオフになっているときにアプリを起動すると、読み込みに少し時間がかかります。

これが私の解決策です(これに基づいています):

https://stackoverflow.com/a/22675607/878126

于 2016-03-30T09:05:25.427 に答える
0

カスタム ローダーを使用している場合は、最後のデータ参照を保存し、getter を介して利用できるようにすることができます。ユーザーが画面を回転させると、getLoaderManager().getLoader メソッドからローダーを取得し、参照を返すことができます。私のテストでは、startLoadering が CustomLoader.onLoadFinished までずっと進んでいることに気付きましたが、結果が activity.onLoadFinished に配信されることはありません。回転時にアクティビティ参照が失われると思われます。ところで、ローダーを作成することの優れた点は、LoaderManager によって永続化されることです。ヘッドレスフラグメントの別のフレーバーと考えてください..笑。

Loader loader  =  getLoaderManager().getLoader(LOADER_ID);

if( loader == null )
{
    getLoaderManager().initLoader(LOADER_ID, null, MyActivity.this );
}
else
{
    listAdapter.addAll(((CustomLoader) loader).getLastData());
}
于 2015-08-03T16:50:26.190 に答える