1

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

Android 文档中的 LoaderManager.restartLoader()

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 的加载器,为什么还要使用“restart”重新创建加载器。谢谢

4

1 回答 1

1

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

如果之前已经启动了具有相同 id 的加载器,它将在新加载器完成其工作时自动销毁。回调将在旧加载器被销毁之前传递。

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

我认为可以帮助您的方法是onContentChanged(),它将为Loader. 您可以使用LoaderManager's getLoader(int)方法来获取对Loader您已经开始的引用并调用该方法来触发您的刷新。

编辑:最初建议使用startLoading ()作为. forceLoad()也是一种可能性,但我建议使用,因为这就是我过去成功的方法。onContentChanged()LoaderManageronContentChanged()

于 2013-10-09T21:12:05.457 回答