android - 无法重新启动 android AsyncTaskLoader

标签 android android-loader asynctaskloader

在 onCreate() 中初始化 Loader 并在按下按钮时重新启动 Loader 的简单代码。关于 android 文档 getLoaderManager().restartLoader() 应该在这个管理器中启动一个新的加载器或重新启动一个现有的加载器。但是每次当我按下按钮并调用 restartLoader 时,它都会创建新的 AbstractLoader。

LoaderManager.restartLoader() in Android documentation

public class MainActivity extends Activity implements LoaderCallbacks<String>{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    getLoaderManager().initLoader(1, null, this); //id is the same
}

@Override
public android.content.Loader<String> onCreateLoader(int id, Bundle args) {
    return new AbstractLoader(this);
}

@Override
public void onLoadFinished(android.content.Loader<String> arg0, String arg1) {
    // TODO Auto-generated method stub
}

@Override
public void onLoaderReset(android.content.Loader<String> arg0) {
    // TODO Auto-generated method stub
    
}

public void click(View v){ //button clicked
    getLoaderManager().restartLoader(1, null, this); //id is the same
}
}

这里是 AbstractLoader 代码:

public class AbstractLoader extends AsyncTaskLoader<String>{

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

 String mResult;

    @Override public String loadInBackground() {
        if (mResult == null) {
            mResult = "Test_String";
        }


        return mResult;
    }

    @Override public void deliverResult(String apps) {
        if (isReset()) {
            if (apps != null) {
                onReleaseResources(apps);
            }
        }
        mResult = apps;

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

    }

    @Override protected void onStartLoading() {
        Log.e("!LOG!", "onStartLoading " + mResult); //mResult is null each time
        if (mResult != null) {
            deliverResult(mResult);
        }


        if (takeContentChanged() || mResult == null) {
            forceLoad();
        }
    }

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

    @Override public void onCanceled(String apps) {
        super.onCanceled(apps);

        onReleaseResources(apps);
    }

    @Override protected void onReset() {
        super.onReset();

        onStopLoading();

        if (mResult != null) {
            onReleaseResources(mResult);
            mResult = null;
        }
    }

    protected void onReleaseResources(String apps) {
    }

}

我需要 mResult 值,因为我只想在 5 分钟内加载一次数据,在另一种情况下我想返回以前的结果。我的问题是:即使我在 onCreate 中使用 initLoader 创建了一个具有相同 ID 的加载器,为什么会用“重新启动”重新创建加载器。 谢谢

最佳答案

根据方法名称到底发生了什么有点模棱两可,但我认为文档中的这一行解释了您描述的行为:

If a loader with the same id has previously been started it will automatically be destroyed when the new loader completes its work. The callback will be delivered before the old loader is destroyed.

我不太确定它是如何工作的,但听起来 restartLoader() 方法会创建一个新的 Loader,获取新数据,然后然后允许您在旧的 Loader 数据消失之前潜在地合并或以其他方式与之交互,而不是 initLoader 只允许获取新信息.

我觉得可以帮到你的方法是onContentChanged() ,这将为 Loader 获取新数据。您可以使用 LoaderManagergetLoader(int)方法来获取对您已经开始使用的 Loader 的引用,并调用该方法触发您的刷新。

编辑:最初建议使用 startLoading()作为 onContentChanged() 的替代方法,但是根据文档,在使用 LoaderManager 时不应调用它。 forceLoad()也是一种可能性,但我建议使用 onContentChanged(),因为这是我过去取得的成功。

关于android - 无法重新启动 android AsyncTaskLoader,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19282645/

相关文章:

android - 无法解析类型 org.apache.http.Header。它是从所需的 .class 文件中间接引用的

android - 如何将 MapView 从像素缩放到米

android - SurfaceView 在 Android 4.1+ 中不再绘制位图

android - 如何正确停止loader?

android - 在 onLoadFinished 方法中启动 Activity

android - ContentProvider、Loader 和 ProgressBar

android - 我应该在 AsyncTaskLoader 内对我自己的 SQLite DB 执行插入、删除、更新吗

android - 在 AsyncTaskLoader 的 loadInBackground 中运行异步方法

java - 是否有适用于 Android 的面向指令的分析工具?

android - 如何中断AsyncTaskLoader的后台线程?