Android 从onLoadFinished()中的光标填充小部件
我想知道如何使用Android 从onLoadFinished()中的光标填充小部件,android,android-cursorloader,Android,Android Cursorloader,我想知道如何使用CursorLoader来填充屏幕上的小部件。所有在线示例都只用于使用适配器,这非常有用。我需要的是一种可靠的方法,可以从光标和UI线程上更新屏幕中的视图,而不会因为StaleDataException或光标突然被停用而崩溃。这是我目前的方法,但我仍然从用户那里收到一些崩溃报告 @Override public Loader<Cursor> onCreateLoader(int id, Bundle arg1) { CursorLoader l
CursorLoader
来填充屏幕上的小部件。所有在线示例都只用于使用适配器,这非常有用。我需要的是一种可靠的方法,可以从光标和UI线程上更新屏幕中的视图,而不会因为StaleDataException
或光标突然被停用而崩溃。这是我目前的方法,但我仍然从用户那里收到一些崩溃报告
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
CursorLoader loader = null;
switch (id) {
case LOADER_ID_DATA:
loader = new CursorLoader(...);
break;
}
return loader;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, final Cursor cursor) {
handler.post(new Runnable() {
@Override
public void run() {
if (getActivity() == null)
return;
updateView(cursor);
}
});
}
@Override
public void onLoaderReset(Loader<Cursor> arg0) {
}
@覆盖
公共加载器onCreateLoader(int-id,Bundle arg1){
游标加载程序加载程序=null;
开关(id){
案例加载器\u ID\u数据:
加载器=新的游标加载器(…);
打破
}
返回装载机;
}
@凌驾
public void onLoadFinished(加载程序,最终光标){
handler.post(新的Runnable(){
@凌驾
公开募捐{
如果(getActivity()==null)
返回;
更新视图(游标);
}
});
}
@凌驾
公共void onLoaderReset(加载程序arg0){
}
一种解决方案是直接检索onLoadFinished中的所有游标字段,并将它们全部传递给处理程序,以填充UI线程上的小部件。但这很难看,因为光标中可能有很多值。我很想找到一种可靠的无崩溃方式来处理这一切。在询问了#android dev
SimonVT
和readme
之后,帮助我弄清了真相
没有任何声明会在UI线程上调用
onLoadFinished
,因此理论上您应该使用一个处理程序,就像Reto的书中建议的那样。但是,当使用CursorLoader
(这是目前最常见的用例)时,您几乎可以保证将在UI线程中调用onLoadFinished
“一种解决方案是直接检索onLoadFinished中的所有游标字段,并将它们全部传递给处理程序,以填充UI线程上的小部件”-onLoadFinished()
在主应用程序线程上被调用。@据我所知,Commonware在主UI线程上没有调用onLoadFinished。例如,如果您查看Reto Meier编写的android-protips_位置源代码,他使用处理程序用值填充小部件。以及他在onLoadFinished()上的注释他计划在主应用程序线程上进行更新。文档示例(例如,在CursorAdapter
上调用swapCursor()
)要求在主应用程序线程上调用它。我编写了使用Loader
的项目,可以直接从onLoadFinished()更新UI
,例如:。并且,文档明确指出“加载器的子类(例如AsyncTaskLoader)通常会在单独的线程中执行其工作,但在交付其结果时,也应该在主线程上执行。“这很奇怪,因为在雷托的《支持android 4》一书中,他说了同样的事情——我自己在android文档中没有看到过,也没有在与UI线程交互时遇到任何问题……@AlexLockwood:正如公认的答案所指出的,Android SDK中的Loader
的唯一具体实现——以及从AsyncTaskLoader
继承的任何其他内容——在主应用程序线程上调用onLoadFinished()
。Reto是正确的,因为文档没有明确说明在主应用程序线程上调用了onLoadFinished()
。但文档中几乎从未说明在主应用程序线程上调用某个给定方法时该方法的状态,因此这并不少见。之所以出现“相当”的情况,是因为CursorLoader使用AsyncTask进行后台工作,使用静态处理程序回发,并最终调用onLoadFinished。如果从主线程调用LoaderManager.initLoader(…),则处理程序也保证连接到主线程。如果此处理程序没有连接到主线程,则必须使用循环器创建一个线程,并从那里启动加载程序。