android - ListFragment doesn't update data from CursorLoader -
i need show data server. there several fragments items can displayed, not easy mantain updates. decided cache data in db , use contentprovider access it. have strange issue.
initially, there no data in database. create cursorloader
, set cursoradapter
adapter listfragment
. receive server , insert several records. supposed loader automatically notified them , reload data. nothing happens, , listfragment stays empty.
the other strange thing related. i've wrote code add actionbar menu fragment. in situation oncreateoptionsmenu
not called (despite of sethasoptionsmenu(true)
in oncreate
) , menu not added. when db has data, works normally.
it seems broken inside fragment
, there nothing in logs. think, doing wrong?
here sample fragment, works this:
import android.database.cursor; import android.os.bundle; import android.support.v4.app.listfragment; import android.support.v4.app.loadermanager; import android.support.v4.content.cursorloader; import android.support.v4.content.loader; import android.support.v4.widget.simplecursoradapter; import android.view.menu; import android.view.menuinflater; public class feedfragment3 extends listfragment implements loadermanager.loadercallbacks<cursor> { private static final int loader_id = 1; private simplecursoradapter madapter; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); sethasoptionsmenu(true); } @override public void onresume() { super.onresume(); getactivity().getactionbar().settitle(r.string.feed_ab_title); } @override public void oncreateoptionsmenu(menu menu, menuinflater inflater) { inflater.inflate(r.menu.feed, menu); } @override public void onactivitycreated(bundle savedinstancestate) { super.onactivitycreated(savedinstancestate); madapter = new simplecursoradapter(getactivity(), android.r.layout.simple_list_item_1, null, new string[] {"title"}, new int[] {android.r.id.text1} ); setlistadapter(madapter); getactivity().getsupportloadermanager().initloader(loader_id, null, this); } @override public loader<cursor> oncreateloader(int id, bundle args) { return new cursorloader(getactivity(), consts.getfeedcontenturi(), null, null, null, null); } @override public void onloadfinished(loader<cursor> loader, cursor data) { madapter.changecursor(data); } @override public void onloaderreset(loader<cursor> loader) { madapter.changecursor(null); } }
here part of contentprovider. suppose calling notifychange
in insert
, setnotificationuri
in query
make contentprovider notified changes. may not enough?
public class feedcontentprovider extends contentprovider { ... @override public cursor query(uri uri, string[] projection, string selection, string[] selectionargs, string sortorder) { dplog.it(tag, "query: [%s]", uri); sqlitequerybuilder qb = new sqlitequerybuilder(); qb.settables("feed"); qb.setprojectionmap(mprojectionmap); cursor c = qb.query(db, projection, selection, selectionargs, null, null, null); c.setnotificationuri(getcontext().getcontentresolver(), uri); return c; } @override public uri insert(uri uri, contentvalues values) { dplog.it(tag, "insert: [%s]", uri); string tablename = mtablenamesforcode.get(murimatcher.match(uri)); mdb.getwritabledatabase().insert(tablename, null, values); getcontext().getcontentresolver().notifychange(uri, null); return uri; } ... }
opening fragment in activity:
private void openfeedfragment() { mfeedfragment = new feedfragment3(); showrootfragment(mfeedfragment); updatefeed(); } private void updatefeed() { mapi.requestfeed( new response.listener<feedresponse>() { @override public void onresponse(feedresponse response) { uri uri = postscontract.getfeedcontenturi(); set<long> existingids = getpostids(uri); arraylist<contentprovideroperation> operations = createmergeoperations(); try { getcontentresolver().applybatch(postscontract.authority, operations); } catch (remoteexception e) { ... } catch (operationapplicationexception e) { ... } } }, null ); }
logs when creating fragment
03-21 19:12:35.041 22005-22344/com.app d/app.contentprovider﹕ cursor size: [0] 03-21 19:12:35.061 22005-22005/com.app v/app.checkpoint-checkpoint﹕ com.app.ui.fragment.feedfragment3.onloadfinished (feedfragment3.java:60) 03-21 19:12:36.012 22005-22066/com.app d/app.api﹕ request 'feed' finished 03-21 19:12:36.092 22005-22066/com.app d/dalvikvm﹕ gc_for_alloc freed 1417k, 11% free 12805k/14256k, paused 25ms, total 25ms 03-21 19:12:36.122 22005-22005/com.app i/app.contentprovider﹕ query: [content://com.app.content.posts/feed] (postscontentprovider.java:59) 03-21 19:12:36.122 22005-22005/com.app d/app.contentprovider﹕ cursor size: [0] (postscontentprovider.java:78) 03-21 19:12:36.142 22005-22005/com.app i/app.contentprovider﹕ insert: [content://com.app.content.posts/feed] (postscontentprovider.java:97) 03-21 19:12:36.262 22005-22005/com.app d/app.contentprovider﹕ inserted id: [1] (postscontentprovider.java:102) ... 03-21 19:12:37.453 22005-22005/com.app d/app.contentprovider﹕ inserted id: [21] (postscontentprovider.java:102) 03-21 19:12:37.453 22005-22348/com.app i/app.contentprovider﹕ query: [content://com.app.content.posts/feed] (postscontentprovider.java:59) 03-21 19:12:37.453 22005-22348/com.app d/app.contentprovider﹕ cursor size: [21] (postscontentprovider.java:78) 03-21 19:12:37.463 22005-22073/com.app i/app.contentprovider﹕ query: [content://com.app.content.posts/feed] (postscontentprovider.java:59) 03-21 19:12:37.463 22005-22073/com.app d/app.contentprovider﹕ cursor size: [21] (postscontentprovider.java:78) 03-21 19:12:37.463 22005-22005/com.app v/app.checkpoint-checkpoint﹕ com.app.ui.fragment.feedfragment3.onloadfinished (feedfragment3.java:60)
in code :-
use swapcursor(data)
instead of changecursor(data)
@override public loader<cursor> oncreateloader(int id, bundle args) { return new cursorloader(getactivity(), consts.getfeedcontenturi(), null, null, null, null); } @override public void onloadfinished(loader<cursor> loader, cursor data) { madapter.swapcursor(data); } @override public void onloaderreset(loader<cursor> loader) { madapter.swapcursor(null); }
try
Comments
Post a Comment