无法重启android AsyncTaskLoader

时间:2013-10-09 21:01:37

标签: android android-loader asynctaskloader

onCreate()中init 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分钟内只加载一次数据,在另一种情况下我想要返回之前的结果。我的问题是:为什么使用“重启”重新创建加载器,即使我使用initLoader在onCreate中创建了具有相同ID的加载器。 感谢

1 个答案:

答案 0 :(得分:1)

对于根据方法名称发生的确切结果,这有点含糊不清,但我认为文档中的这一行解释了您描述的行为:

  

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

我不确定这是如何工作的,但听起来restartLoader()方法会创建一个新的Loader,抓取新数据,然后允许您可能合并或否则会在旧的Loader数据消失之前与其进行交互,而initLoader则只允许获取新信息。

我认为可以帮助您的方法是onContentChanged(),它会获取Loader的新数据。您可以使用LoaderManager的{​​{3}}方法获取对您已启动的Loader的引用,并调用该方法触发刷新。

修改:最初建议使用getLoader(int)替代onContentChanged(),但根据文档,使用LoaderManager时不应调用。 startLoading()也是可能的,但我建议使用onContentChanged(),因为这是我过去取得的成功。