我是android的新手,我不确定我是否正在寻找可能,是否有可能从一个线程更新装载程序管理器处理的listview内容?如果可以,请告诉我如何?
下面有更多详细信息,为简洁起见,我删除了很多行,如果您需要更多详细信息,请与我们联系
我正在使用的HandlerThread就是这个,我需要通知加载器有关更改列表视图内容的更改
public void syncWithBackend(Context context) {
//Connect to the server over HTTP and get the latest data after receiving
//the GCM tickle message then save the result in DB
dbhelper.saveFm(id, artno, comment );
//Here is where I need to notify the loader or the list about the new change
// to view the new saved data
context.getContentResolver().notifyChange(uri, null);
}
我正在使用的URI是belwo,
Uri uri = Uri.parse("sqlite://com.pack.android.and/posts");
我的LoaderCallbacks就是这个
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new FeedListCursorLoader(getActivity());
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
cCursorAdapter adapter = new cCursorAdapter(getActivity(),
(fCursor) cursor);
setListAdapter(adapter);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
setListAdapter(null);
}
我的意图服务就是这个
protected void onHandleIntent(Intent intent) {
//Here I got the GCM message, call the thread to sync with the backend
hanlder1.queueHttp(this);
}
我的AsyncTaskLoader是这个
public abstract class SQLiteCursorLoader extends AsyncTaskLoader<Cursor> {
private Cursor cCursor;
public SQLiteCursorLoader(Context context) {
super(context);
}
//I'm overriding this from the Fragment to get the cursor after querying sqlite DB
protected abstract Cursor loadCursor();
@Override
public Cursor loadInBackground() {
Cursor cursor = loadCursor();
if (cursor != null) {
cursor.getCount();
cursor.setNotificationUri(getContext().getContentResolver(), uri);
}
return cursor;
}
@Override
public void deliverResult(Cursor data) {
Cursor oldCursor = cCursor;
cCursor = data;
if (isStarted()) {
super.deliverResult(data);
}
if (oldCursor != null && oldCursor != data && !oldCursor.isClosed()) {
oldCursor.close();
}
}
@Override
protected void onStartLoading() {
...
}
@Override
protected void onStopLoading() {
...
}
@Override
public void onCanceled(Cursor cursor) {
...
}
@Override
protected void onReset() {
...
}
答案 0 :(得分:1)
是的,但并不像你期望的那样。
您不会更新光标,您将替换它。事实上,LoaderManager
会自动为您完成。它几乎令人难以置信的简单
创建游标时,为响应Loader
的请求,将其注册为特定URI的侦听器:
cursor.setNotificationUri(getContext().getContentResolver(), uri);
URI可以是您想要的任何内容。它代表(是?的“名称”)数据。
当Loader
运行LoaderManager
时,LoaderManager
会在回调中获得Loader
返回的光标,然后再将其传递给您。 它在该光标上注册为侦听器。
如果在此之后的某个时刻,您宣布在该URI所代表的数据中发生了更改,请执行以下操作:
getContext().getContentResolver().notifyChange(uri, null);
将通知光标(在该URI上注册为侦听器)。当通知光标时,将通知LoaderManager
(在光标上注册为监听器),它将自动重新运行Loader!
在你的情况下,你会在另一个线程上做通知......
如果您的onLoadFinished
方法只是换出旧光标并换入新光标,那么ListView
将通过魔法更新。
Android的某些部分非常棒。
编辑添加示例代码:
以下是一些示例代码,用于演示其工作原理。 db
是对SQLiteOpenHelper
的引用。方法insert
和query
分别是简单的数据库插入和查询。
首先是插入代码:
db.insert();
getContentResolver().notifyChange(DbHelper.URI, null);
然后是装载机:
private static class MagicLoader extends AsyncTaskLoader<Cursor> {
private final DbHelper db;
private volatile Cursor cursor;
private final ContentObserver obs = new ContentObserver(new Handler()) {
@Override public boolean deliverSelfNotifications() { return true; }
@Override public void onChange(boolean selfChange) { onContentChanged(); }
};
public MagicLoader(Context ctxt, DbHelper db) {
super(ctxt);
this.db = db;
}
@Override
protected void onStartLoading() {
if (null == cursor) { forceLoad(); }
else { deliverResult(cursor); }
}
@Override
public Cursor loadInBackground() {
cursor = db.query();
if (cursor != null) {
try {
cursor.setNotificationUri(
getContext().getContentResolver(),
DbHelper.URI);
cursor.getCount();
cursor.registerContentObserver(obs);
}
catch (RuntimeException ex) {
cursor.close();
throw ex;
}
}
return cursor;
}
};
请注意,如果您只使用ContentProvider
,这将更容易。