对我来说,如果您有多个装载机,如何获得正确的光标并不清楚.让我们说你定义了两个不同的Loader:
getLoaderManager().initLoader(0,null,this);
getLoaderManager().initLoader(1,null,this);
Run Code Online (Sandbox Code Playgroud)
然后在onCreateLoader()中你根据id做不同的事情:
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
if (id==0){
CursorLoader loader = new CursorLoader(getActivity(),
MaterialContentProvider.CONTENT_URI,null,null,null,null);
}else{
CursorLoader loader = new CursorLoader(getActivity(),
CustomerContentProvider.CONTENT_URI,null,null,null,null);
};
return loader;
}
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好.但是如何在onLoadFinished()中获得正确的光标,因为你没有得到任何id来识别正确的Cursoradapter光标.
@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {
mycursoradapter1.swapCursor(cursor);
if(isResumed()){
setListShown(true);
}else {
setListShownNoAnimation(true);
}
}
//and where to get the cursor for mycursoradapter2
Run Code Online (Sandbox Code Playgroud)
或者我错了,这是在一个片段中获得两个不同cursoradapter的结果的错误方法.
我正试图弄清楚如何Loaders在Android 3.0中使用,但似乎无法让它工作.文档只描述使用,CursorLoader但我正在使用AsyncTaskLoader.
从文档中看来,您应该只需要实现,AsyncTaskLoader.loadInBackground()但它永远不会被调用getLoaderManager().initLoader(),然后在回调中创建加载器.
我可以看到调试消息说它Created new loader LoaderInfo{4040a828 #0 : ArticleDataLoader{4036b350}}好像是成功创建的.
是否有可能在SDK中破坏了加载器,或者在创建加载器后是否需要调用某些方法?(他们在CursorLoader示例中没有这样做).
编辑:似乎调用forceLoad()返回的Loader initLoader()至少启动加载,但这意味着你无法正确处理旋转:(
android android-3.0-honeycomb android-loadermanager android-loader
我阅读了关于装载机的android指南.我阅读了Alex Lockwood的4部分教程.也测试了他的示例应用程序.试图阅读谷歌应用程序的I/O 13,有一个流功能,阅读其代码发现它使用加载器,因为它提供了创建代码的代码StreamLoader.这是链接
我想他们用它来监控新数据并将它们添加到他们的视图中.
Alex的应用程序也是如此.有一个观察者,当有新的数据条目触发UI的刷新.
到目前为止,在我看来,Loaders是"livescore"应用的理想选择.当有新的更新(这意味着新的数据输入)时,它会出现在您的屏幕上.
也许像Twitter这样的东西.为您自己的新消息,自定义Observer通知更改,自定义Loader带来数据和适配器显示它们.无需"拉动刷新".但是,Twitter又有了自己的RESTful API,它有点做同样的工作.不需要指向新数据的指针.(不知道他们是怎么做的,但我想某种程度上"推送"你的设备的新数据).
所以我的问题是:
当我们想要观察数据源并 更改我们的视图以便显示新数据时,装载程序是最佳选择吗?
是否有任何示例/应用程序我可以检查处理该逻辑:监视数据源 - >获取数据 - >刷新UI
任何特征情况(如我之前提到的"实时评分"),当我们必须处理它们时,我们必须选择装载机?
加载器的第二部分(配置改变,保持数据)我认为它清楚.当用户旋转设备时,没有人想要重新下载图库.
谢谢你,原谅我的困惑
我有一个CursorLoader直接使用SQLite数据库而不是使用的自定义ContentProvider.这个加载器使用a ListFragment支持CursorAdapter.到现在为止还挺好.
为了简化操作,我们假设UI上有一个Delete按钮.当用户单击此按钮时,我会从数据库中删除一行,并调用onContentChanged()我的加载程序.此外,在onLoadFinished()回调时,我调用notifyDatasetChanged()我的适配器以刷新UI.
当删除命令快速连续发生时,意味着快速连续onContentChanged()调用,bindView()最终将使用陈旧数据.这意味着行已被删除,但ListView仍在尝试显示该行.这导致了Cursor异常.
我究竟做错了什么?
这是一个自定义的CursorLoader(基于Diane Hackborn女士的建议)
/**
* An implementation of CursorLoader that works directly with SQLite database
* cursors, and does not require a ContentProvider.
*
*/
public class VideoSqliteCursorLoader extends CursorLoader {
/*
* This field is private in the parent class. Hence, redefining it here.
*/
ForceLoadContentObserver mObserver;
public VideoSqliteCursorLoader(Context context) {
super(context); …Run Code Online (Sandbox Code Playgroud) android asynctaskloader android-loadermanager android-cursorloader android-loader
我正在尝试使用an AsyncTaskLoader在后台加载数据以填充详细信息视图以响应所选的列表项.我已经得到它主要工作,但我仍然有一个问题.如果我在列表中选择第二个项目然后在第一个选定项目的加载完成之前旋转设备,则onLoadFinished()呼叫将报告给正在停止的活动而不是新活动.只选择一个项目然后旋转时,这样可以正常工作.
这是我正在使用的代码.活动:
public final class DemoActivity extends Activity
implements NumberListFragment.RowTappedListener,
LoaderManager.LoaderCallbacks<String> {
private static final AtomicInteger activityCounter = new AtomicInteger(0);
private int myActivityId;
private ResultFragment resultFragment;
private Integer selectedNumber;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myActivityId = activityCounter.incrementAndGet();
Log.d("DemoActivity", "onCreate for " + myActivityId);
setContentView(R.layout.demo);
resultFragment = (ResultFragment) getFragmentManager().findFragmentById(R.id.result_fragment);
getLoaderManager().initLoader(0, null, this);
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d("DemoActivity", "onDestroy for " + myActivityId);
}
@Override
public void onRowTapped(Integer number) {
selectedNumber …Run Code Online (Sandbox Code Playgroud) android asynctaskloader android-loadermanager android-loader
我有点喜欢Volley框架,但我仍然对它有些怀疑.
例如,Volley如何与Loader模式对齐?由于它的请求是以异步方式处理的,因此在后台调用它并没有多大意义.另一方面,如果我们忽略Loader模式,我们将取消加载并重新加载必要的资源,这有点浪费.
Volley框架如何与Android中的Loaders一起使用?
使用Loaders创建Android应用程序时,每个活动和片段都应该有自己的LoaderManager吗?或者应该只有一个LoaderManager应用程序拥有?最后,用于识别LoaderManager课堂外可见特定内容的"唯一ID"是什么?
具体来说,我无法确定应用程序中哪些类应该实现这些LoaderCallback<Cursor>方法(即每个片段应该实现这些回调,还是我应该有一个片段实现回调并查询结果,必要时将它们发送到其他片段/活动) ?
在此先感谢能帮助我的人!我在网上找不到太多关于此的信息.
据我所知,Loader框架适用于访问ContentProvider/SQLite数据库中本地存储的数据.我们有CursorLoader类可以很好地处理这个用例.
但我想知道使用Loader框架编写扩展Loader/AsyncTaskLoader以访问远程Web服务(例如REST Web服务)的类是否切实可行?我一直认为这个框架对于这个用例来说有点过于僵化和混乱(缺乏适当的文档).我更喜欢使用AsyncTasks/Services以更常规的方式处理REST调用.但最近我发现一些使用AsyncTaskLoaders的文章并开始怀疑.
那么为什么有人会使用Loaders来访问Web服务呢?我在这里看到的唯一优势是装载机自动保留其结果.之后没有Cursor可以管理.
LoaderManager有这个方法restartLoader():
public abstract Loader<D> restartLoader (int id, Bundle args, LoaderCallbacks<D> callback)在此管理器中启动新的或重新启动现有的Loader,向其注册回调,并且(如果活动/片段当前已启动)开始加载它.如果先前已启动具有相同id的加载器,则在新加载器完成其工作时将自动销毁该加载器.回调将在旧的加载器被销毁之前传递.
基于开发指南,我得到的结论是,确实,调用onCreateLoader将始终来自restartLoader():
重新启动加载程序
...
要丢弃旧数据,请使用restartLoader().例如,当用户的查询更改时,SearchView.OnQueryTextListener的此实现会重新启动加载程序.需要重新启动加载程序,以便它可以使用修订的搜索过滤器来执行新查询:
public boolean onQueryTextChanged(String newText) {
// Called when the action bar search text has changed. Update
// the search filter, and restart the loader to do a new query
// with this filter.
mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
getLoaderManager().restartLoader(0, null, this);
return true;
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
// NOTE: …Run Code Online (Sandbox Code Playgroud) 我正在使用AsyncTaskLoader.我有一个已经实现的活动LoaderCallbacks(支持库).
我有断点调试并放入日志,加载器传递结果,但是第二次onLoadFinished没有触发回调.奇怪的是 - 当我再次向后旋转时它起作用,当我回到它时,我开始的方向会得到回调.
在我的活动中onResume:
LoaderManager lm = getSupportLoaderManager();
Loader loader = lm.initLoader(0, null, new LoaderManager.LoaderCallbacks<String>() {
@Override
public Loader<String> onCreateLoader(int i, Bundle bundle) {
Loader<String> loader = new TestLoader(MainActivity.this);
return loader;
}
@Override
public void onLoadFinished(Loader<String> stringLoader, String s) {
Log.d(Application.TAG, "OnLoadFinished " + s);
doStuff(s);
}
@Override
public void onLoaderReset(Loader<String> stringLoader) {
// NOP
}
});
Run Code Online (Sandbox Code Playgroud)
在我的装载机:
public class TestLoader extends AsyncTaskLoader<String> {
private String mData;
public TestLoader(Context context) { …Run Code Online (Sandbox Code Playgroud)