2013-10-09 43 views
1

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

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

这是一种模棱两可基于该方法的名称究竟发生了什么,但我认为这条线从文档中解释的行为你描述:

如果用相同的装载机id以前已经启动,它会在新加载器完成其工作时自动销毁。回调将在旧加载器销毁之前交付。

我不能完全肯定这是如何工作的引擎盖下,但它听起来像restartLoader()方法将创建一个新的Loader,抢新鲜的数据,然后让你的潜在合并或以其他方式与旧互动Loader的数据在它消失之前,而不是initLoader,它将只允许提取新的信息。

我认为可以帮助你的方法是onContentChanged(),它将获取Loader的新数据。您可以使用LoaderManagergetLoader(int)方法获取对您开始使用的Loader的引用,并调用该方法触发刷新。

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