Android LoaderManager.restartLoader()是否总是导致调用onCreateLoader()?
Android LoaderManager.restartLoader()是否总是导致调用onCreateLoader()?,android,android-loadermanager,android-loader,Android,Android Loadermanager,Android Loader,LoaderManager具有以下方法: 公共抽象加载程序restartLoader(int-id、Bundle-args、LoaderCallbacks回调) 在此管理器中启动新加载程序或重新启动现有加载程序,向其注册回调,然后(如果活动/片段当前已启动)开始加载它。如果以前启动过具有相同id的加载程序,则当新加载程序完成其工作时,该加载程序将自动销毁。回调将在旧加载程序销毁之前传递 基于,我得到的想法是,调用onCreateLoader总是从restartLoader(): 重新启动加载程序
LoaderManager
具有以下方法:
公共抽象加载程序restartLoader(int-id、Bundle-args、LoaderCallbacks回调)
在此管理器中启动新加载程序或重新启动现有加载程序,向其注册回调,然后(如果活动/片段当前已启动)开始加载它。如果以前启动过具有相同id的加载程序,则当新加载程序完成其工作时,该加载程序将自动销毁。回调将在旧加载程序销毁之前传递
基于,我得到的想法是,调用onCreateLoader
总是从restartLoader()
:
重新启动加载程序
要丢弃旧数据,请使用restartLoader()。例如,SearchView.OnQueryTextListener的此实现在用户的查询更改时重新启动加载程序。加载程序需要重新启动,以便可以使用修改后的搜索筛选器执行新查询:
public boolean onquerytexchanged(字符串newText){
//当操作栏搜索文本已更改时调用。更新
//搜索筛选器,然后重新启动加载程序以执行新查询
//用这个过滤器。
mCurFilter=!TextUtils.isEmpty(newText)?newText:null;
getLoaderManager().restartLoader(0,null,this);
返回true;
}
公共加载器onCreateLoader(int-id,Bundle-args){
//注意:加载程序是用用户的查询实例化的
uribaseuri;
if(mCurFilter!=null){
baseUri=Uri.withAppendedPath(Contacts.CONTENT\u FILTER\u Uri,
encode(mCurFilter));
}否则{
baseUri=Contacts.CONTENT\u URI;
}
//现在创建并返回一个游标加载程序,它将处理
//为正在显示的数据创建光标。
String select=“(“+Contacts.DISPLAY_NAME+”NOTNULL)和(”
+Contacts.HAS_PHONE_NUMBER+“=1)和(”
+Contacts.DISPLAY_NAME+“!=”);
返回新的游标装入器(getActivity(),baseUri,
联系人\u摘要\u投影,选择,空,
Contacts.DISPLAY_NAME+“核对本地化ASC”);
}
在本例中,
onCreateLoader
是将有关用户查询的信息传递给加载程序的唯一位置(在实例化时)。但是,这些文档会说“启动一个新的或重新启动一个现有的加载程序”这让我很反感。您的问题的简单答案是肯定的,对restartLoader()的调用将再次调用onCreateLoader()
您可以并行启动多个加载程序(假设您有两个SimpleCorsorAdapter要填充),例如:
然后,加载程序管理器为每个id调用onCreateLoader(然后,加载程序管理器异步构建返回的加载程序):
…首先调用onLoaderReset:
public void onLoaderReset(Loader<Cursor> loader)
{
if (loader.getId() == 0)
//perhaps do swapCursor(null) on an adapter using this loader
else if (loader.getId() == 1)
//perhaps do swapCursor(null) on an adapter using this loader
}
public void onLoaderReset(加载程序)
{
if(loader.getId()==0)
//可能使用此加载程序在适配器上执行swapCursor(null)
else if(loader.getId()==1)
//可能使用此加载程序在适配器上执行swapCursor(null)
}
…之后是对onCreateLoader的新调用。因此,在这方面,onCreateLoader既可用于启动全新的加载程序,也可用于重置现有加载程序。我很想知道为什么您会这样认为?这就是加载程序与ContentProvider/Datasource异步交互的全部要点。长时间运行的任务(可能会阻塞UI)在onCreateLoader中运行—LoaderManager在后台运行该部分。是的,是的,AsyncTaskLoader的部分肯定在后台线程上运行,但我认为onCreateLoader在UI线程上:--与实例化
异步任务
相当,这就是我的推理。从客户机/主线程对加载程序的调用是.initLoader()调用。然后加载程序在后台运行onCreateLoader;似乎onCreateLoader在UI线程上运行。我还在onCreateLoader中添加了一些UI更新,它可以正常工作。@ANemati谢谢;再看一遍,你是对的。onCreateLoader确实在UI线程上运行—它返回的加载程序是由加载程序管理器异步构建的。我已编辑了我的答案,以消除不准确之处。
getLoaderManager().initLoader(0, null, this); //id = 0
getLoaderManager().initLoader(1, null, this); //id = 1
public Loader<Cursor> onCreateLoader(int id, Bundle args)
{
if (id == 0)
//return a Loader<Cursor> for id 0
else if (id == 1)
//return a Loader<Cursor> for id 1
}
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor)
{
if (loader.getId() == 0)
//cursor was returned from onCreateLoader for id 0
//perhaps do swapCursor(cursor) on an adapter using this loader
else if (loader.getId() == 1)
//cursor was returned from onCreateLoader for id 1
//perhaps do swapCursor(cursor) on an adapter using this loader
}
getLoaderManager().restartLoader(0, null, this); //id = 0
public void onLoaderReset(Loader<Cursor> loader)
{
if (loader.getId() == 0)
//perhaps do swapCursor(null) on an adapter using this loader
else if (loader.getId() == 1)
//perhaps do swapCursor(null) on an adapter using this loader
}