Articles of android loader

为什么在片段恢复后再次调用onLoadFinished?

我对装载机有一个特殊的问题。 目前我不确定这是否是我的代码中的错误或我误解了加载器。 该应用程序 问题出现在对话中(想象类似于Whatsapp的东西)。 我使用的加载器是基于AsyncTaskLoader示例实现的 。 我正在使用支持库。 在OnCreate中,我启动一个加载器来检索缓存的消息。 当CachedMessageLoader完成时,它启动RefreshLoader以检索(在线)最新消息。 每个加载器types作为不同的ID(例如,离线:1在线:2) 这非常有效,但有以下例外。 问题 当我打开另一个片段(并将事务添加到backstack)然后使用Back-Key返回conversationFragment时,再次使用之前的两个结果调用onLoadFinished 。 此调用发生在片段有机会再次启动加载器之前… 我之前获得的“旧”结果的传递导致重复的消息。 题 为什么这些结果再次传递? 我是否错误地使用这些装载机? 我可以“使结果无效”以确保我只将它们送到一次或者我必须自己消除重复吗? 堆栈跟踪的电话 MyFragment.onLoadFinished(Loader, Result) line: 369 MyFragment.onLoadFinished(Loader, Object) line: 1 LoaderManagerImpl$LoaderInfo.callOnLoadFinished(Loader, Object) line: 427 LoaderManagerImpl$LoaderInfo.reportStart() line: 307 LoaderManagerImpl.doReportStart() line: 768 MyFragment(Fragment).performStart() line: 1511 FragmentManagerImpl.moveToState(Fragment, int, int, int, boolean) line: 957 FragmentManagerImpl.moveToState(int, int, int, boolean) line: 1104 […]

在Android中使用Asynctask的加载器有什么优势?

加载器优于异步任务有什么优势吗? 此外,如何使装载程序与Android froyo手机兼容。 编辑: 这里的主要问题是我没有使用本机DB(SqlLite)。 在开发服务器上使用DB。 显然,我不能再使用CursorLoader了。 AsyncTaskLoader完全没有示例。 如果有的话,请做链接。 将所需数据加载到本地数据库然后使用CursorLoader查询它是否更好?

除了过早调用cursor.close()之外,什么可能导致StaleDataException?

我目前正在大量修改/重写一个Android应用程序,我看到一个非常偶然的崩溃沿着以下几行:调用CursorAdapter方法,它调用AbstractWindowedCursor#checkPosition() ,和: 02-20 15:03:18.180 E/AndroidRuntime(17143): android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method. 02-20 15:03:18.180 E/AndroidRuntime(17143): at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139) 02-20 15:03:18.180 E/AndroidRuntime(17143): at android.database.AbstractWindowedCursor.getLong(AbstractWindowedCursor.java:74) 02-20 15:03:18.180 E/AndroidRuntime(17143): at android.database.CursorWrapper.getLong(CursorWrapper.java:106) 02-20 15:03:18.180 E/AndroidRuntime(17143): at android.widget.CursorAdapter.getItemId(CursorAdapter.java:220) 麻烦的是,我们没有关闭任何Cursor 。 我们所有的Cursor都来自CursorLoader而且是由ContentProvider生成的。 我们将Cursor从LoaderCallbacks传递到每个相应的CursorAdapter ,我们在ContentProvider注册Cursor用于通知,我们从每个insert(…) , delete(…)和update(…) 通知) ContentResolver update(…) …简而言之,我找不到任何理由为什么Cursor在使用时会关闭。 那么: StaleDataException的其他原因是StaleDataException […]

Honeycomb Loaders可以解决AsyncTask + UI更新的问题吗?

在后台执行某些操作然后更新UI很难在Android中正确实现。 它设计得很糟糕。 典型的例子是AsyncTask,它从Web中获取内容并显示结果。 这有两个问题: AsyncTask引用了Activity(因为它需要更新其UI)。 屏幕方向更改后,重新启动活动。 但是AsyncTask仍然引用旧的被破坏的Activity,因此无法更新新Activity的UI。 这可能导致OutOfMemoryException。 想象一下,你有一个包含大量位图的Activity,并启动一些AsyncTask。 您按BACK(活动已完成)但AsyncTask仍在运行,并且因为它引用了Activity,所以带有位图的Activity仍在内存中。 重复此操作(开始活动和返回),你的力量迟早会关闭。 这可以解决,但它太复杂了。 在一个Activity中,我有3个不同的AsyncTasks,每个都可以同时在多个实例中运行。 正确实现这一点令人沮丧。 代码变得非常难以理解和调试。 Honeycomb Loaders能以某种方式解决这个问题吗? 有没有办法在pre-Honeycomb Android版本中使用它们?

Loader将结果传递给错误的片段

我有一个基于Android开发人员示例使用ActionBar选项卡滑动选项卡的活动。 每个选项卡显示一个片段,每个片段(实际上是SherlockFragment)通过自定义AsyncTaskLoader加载不同types的远程api请求。 问题是,如果您点击一个选项卡移动2个选项卡/页面,而您要离开的选项卡的片段(旧片段)正在加载结果,则该结果将传递到您移动到的选项卡的片段(新片段)。 在我的情况下,这会导致ClassCastException,因为预期的结果是不兼容的types。 在代码中,情况的要点是: 装载机: public class FooLoader extends AsyncTaskLoader public class BarLoader extends AsyncTaskLoader 片段: public class FooFragment extends Fragment implements LoaderManager.LoaderCallbacks { … @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getLoaderManager().initLoader(0, null, this); } public Loader onCreateLoader(int id, Bundle args) { return new FooLoader(); } … } public class BarFragment extends Fragment […]

LoaderManager.restartLoader()总是会调用onCreateLoader()吗?

LoaderManager有这个方法restartLoader() : public abstract Loader restartLoader (int id, Bundle args, LoaderCallbacks callback) 启动一个新的或重新启动此管理器中的现有Loader,将回调注册到它,并且(如果活动/片段当前已启动)开始加载它。 如果先前已启动具有相同id的加载器,则在新加载器完成其工作时将自动销毁该加载器。 回调将在旧的加载器被销毁之前传递。 基于开发指南 ,我认为实际上,对onCreateLoader的调用总是来自restartLoader() : 重新启动加载程序 … 要丢弃旧数据,请使用restartLoader()。 例如,当用户的查询更改时,SearchView.OnQueryTextListener的此实现会重新启动加载程序。 需要重新启动加载程序,以便它可以使用修订的搜索filter来执行新查询: 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 […]

Android Loader不会在屏幕旋转时触发回调

我正在使用AsyncTaskLoader 。 我有一个已经实现了LoaderCallbacks (支持库)的活动。 我有调试断点并放入日志,加载器传递结果,但是第二次没有触发回调onLoadFinished 。 奇怪的是 – 当我再次向后旋转时,它会工作,当我回到它时,我开始的方向会得到回调。 在我的活动onResume : LoaderManager lm = getSupportLoaderManager(); Loader loader = lm.initLoader(0, null, new LoaderManager.LoaderCallbacks() { @Override public Loader onCreateLoader(int i, Bundle bundle) { Loader loader = new TestLoader(MainActivity.this); return loader; } @Override public void onLoadFinished(Loader stringLoader, String s) { Log.d(Application.TAG, “OnLoadFinished ” + s); doStuff(s); } @Override […]

是否应该使用Loaders访问Web服务?

据我所知,Loader框架适用于访问ContentProvider / SQLite数据库中本地存储的数据。 我们有CursorLoader类可以很好地处理这个用例。 但我想知道使用Loader框架编写扩展Loader / AsyncTaskLoader以访问远程Web服务(例如REST Web服务)的类是否切实可行? 我一直认为这个框架对于这个用例来说有点过于僵化和混乱(缺乏适当的文档)。 我更喜欢使用AsyncTasks / Services以更常规的方式处理REST调用。 但最近我发现一些使用AsyncTaskLoaders的文章并开始怀疑。 那么为什么有人会使用Loaders来访问Web服务呢? 我在这里看到的唯一优势是装载机自动保留其结果。 之后没有Cursor可以管理。

Android Volley + Loader模式?

我有点喜欢Volley框架,但我仍然对它有些怀疑。 例如,Volley如何与Loader模式对齐? 由于它的请求是以异步方式处理的,因此在后台调用它并没有多大意义。 另一方面,如果我们忽略Loader模式,我们将取消加载并重新加载必要的资源,这有点浪费。 Volley框架如何与Android中的Loaders一起使用?

AsyncTaskLoader onLoadFinished有待处理的任务和配置更改

我正在尝试使用AsyncTaskLoader在后台加载数据以填充详细信息视图以响应所选的列表项。 我得到它主要工作,但我仍然有一个问题。 如果我在列表中选择第二个项目,然后在第一个选定项目的加载完成之前旋转设备,则onLoadFinished()调用将向正在停止的活动报告而不是新活动。 这在选择单个项目然后旋转时工作正常。 这是我正在使用的代码。 活动: public final class DemoActivity extends Activity implements NumberListFragment.RowTappedListener, LoaderManager.LoaderCallbacks { 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, […]