Programing

Android AsyncTaskLoader가 loadInBackground를 시작하지 않습니까?

lottogame 2020. 12. 3. 07:20
반응형

Android AsyncTaskLoader가 loadInBackground를 시작하지 않습니까?


Android에서 로더 예제를 구현하려고하는데 로더를 시작할 수 없습니다. 다음 코드를 사용하고 있습니다. "Create Loader"에 도달하지만 "Loading started"로그 메시지에는 도달하지 않습니다. 필요한 전화를 놓치고 있습니까?

활동:

    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");
        }

    }

호환성 라이브러리를 사용하여 동일한 문제가 발생했습니다. 전화로 해결했습니다.forceLoad

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

분명히 AsyncLoader에 대한 문서는 부족하며이 문제는 HoneyComb에도 존재합니다. 자세한 정보는 여기 에서 찾을 수 있습니다 .

AsyncTaskLoader 의 공식 예제 는 forceLoad ()를 호출하므로 버그가 아니지만 여전히 그 동작이 매우 직관적이지 않다고 생각합니다.


재정의 loadInBackground()만으로는 충분하지 않습니다.

상기 봐 가지고 AppListLoaderhttp://developer.android.com/reference/android/content/AsyncTaskLoader.html을 .

최소한 다음 두 가지 방법을 로더에 추가하십시오.

        @Override
        protected void onStartLoading() {
            if (takeContentChanged())
                forceLoad();
        }

        @Override
        protected void onStopLoading() {
            cancelLoad();
        }

onContentChanged()생성자에서 호출 합니다.


rrayst 의 조언은 매우 간결합니다. 다음과 같이 메소드를 작성하면 :

protected void onStartLoading() {
    forceLoad();
}

당신이 ''자식 활동이 나타나고 때 다음, 부모 하나에 반납 LL 통지 onStartLoading(그래서와 loadInBackground) 다시 호출된다!

당신은 무엇을 할 수 있나요? mContentChanged생성자 내부에서 내부 변수 ( )를 true로 설정합니다 . 그런 다음이 변수를 내부에서 확인하십시오 onStartLoading. 사실 일 때만 실제로드를 시작합니다.

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();
    }
}

여기에 (수락 된 것 외에) 답변 중 어느 것도이 문제를 해결하는 데 도움이되지 않았기 때문에 이것이 어떻게 작동했는지 여기에 있습니다.

I don't think the accepted answer is the correct solution, since it causes loadInBackground() to be called more often than necessary, i.e. on orientation change, which does not happen when properly overriding the following methods in the loader as well:

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

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

}

@Override
protected void onStartLoading() {
    if (takeContentChanged() || participants == null) {
        forceLoad();
    }
}

If you are using a custom loader, you can save the last data reference, and have it available via a getter. when the user rotates his screen, you can get the loader back from getLoaderManager().getLoader method, and then return back the reference. For my testing I noticed that startLoadering goes all the way to CustomLoader.onLoadFinished but the result is never deliver to activity.onLoadFinished.I suspect the activity reference gets lost upon rotation. By the way the great thing about creating loaders is they are persistent through LoaderManager. Think of it as another flavor of headless fragments.. lol.

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

if( loader == null )
{
    getLoaderManager().initLoader(LOADER_ID, null, MyActivity.this );
}
else
{
    listAdapter.addAll(((CustomLoader) loader).getLastData());
}

I've found that each of the above solutions have issues, especially when the app starts while the screen is turned off, and the loading takes a few moments.

Here's my solution (base on this):

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

참고URL : https://stackoverflow.com/questions/10524667/android-asynctaskloader-doesnt-start-loadinbackground

반응형