I'm using greenDAO in my android app to display a list of objects in a RecyclerView
. I have a subclass of RecyclerView.Adapter
that takes a list of objects which are greenDAO entities.
What I do in onCreate
is:
null
for my list. This is just to make the adapter known to the RecyclerView
below.RecyclerView
with layout and adapter.This is the relevant code:
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
mLayoutManager = new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false);
mListAdapter = new MyRecyclerAdapter(null);
mList.setHasFixedSize(true);
mList.setLayoutManager(mLayoutManager);
mList.setAdapter(mListAdapter);
refreshItems();
}
public void refreshItems()
{
AsyncSession asyncSession = ((App)getApplication()).getDaoSession().startAsyncSession();
asyncSession.setListenerMainThread(new AsyncOperationListener()
{
@Override
public void onAsyncOperationCompleted(final AsyncOperation operation)
{
if (operation.isCompletedSucessfully())
mListAdapter.setItems((List<Item>) operation.getResult());
}
});
asyncSession.loadAll(Item.class);
}
This works pretty well. Now I noticed, that of course the method that queries the database via greenDAO is invoked every time I rotate the activity or come back to it from another activity. That's pretty clear, since I'm calling that method from onCreate
.
My question is: is it best practice to do this like I'm doing it (requery DAO every time) or should I make my objects parcelable and save the list I have in onSaveInstanceState
and restore it in onRestore
instead of requerying DAO?
What you're doing is completely valid and you don't need to save the queried data in onSaveInstanceState()
, use in-memory cache, or any other optimization (even if GreenDAO wouldn't have internal cache).
In fact, you're more than all-right because you perform the query asynchronously - GreenDAO's creators kind of claim that the queries can be executed on UI thread in most cases (which I find hard to agree with).
I would also suggest that you perform data query in onStart()
instead of onCreate()
. I personally think that onCreate()
should be used only for operations you would otherwise perform in the constructor (e.g. fields initializations). Another reason to perform this query in onStart()
is that if the user leaves your application for a long time and then gets back to it, the data might get outdated (e.g. due to background syncs by SyncAdapter
) and you'll want to refresh it.
The last piece that you might want to add is "data change notifications". You will want this mechanism to be in place if the data that you query and display to the user can change without user's interaction (e.g. due to background syncs by SyncAdapter
). The concept is simple - Activity
registers for notifications about data change in onCreate()
, and if notification received you perform re-query in order to make sure that the user sees an up-to-date data.
I can't claim that the above are "best practices", but they are good practices that work well.
Lazy list:
As @pskink suggested in his comment, you could also employ LazyList
. Be aware, though, that it doesn't obviate a need for async query of data. Usage of LazyList
allows you to perform the query as usual, but load the results into memory in on-demand way. This might be useful if you expect the query to produce lots of data.
In my opinion, however, one should optimize the code only if actual performance problem is being observed. So, unless you know ahead of time that a particular query produces thousands of results, I say you don't need LazyList
.