I need to build a listview with many items.Each item info queries from managerQuery or sqlite.It has some fields: title(String), description(String), path(string). I waver between save info of list object or get info while building each item. Saving info to list object will increase ram and getting info while building each item makes app slow (my listview has large no. of items).
Querying the db every time you build new item will slow down the list scrolling. Getting data before hand is better approach.
Related
Suppose, In my app I have a sqlite table that can contain at most 20 row. Each row has 2 column(id, name). Where I frequently need to search by Id to get Name. For this frequent need I have two solution:
Solution 1: Get rows in a arraylist<model> and then find name from array.
Solution 2: Every time search on sqlite table.
Now please give your opinion which one is better?
Remember again, I need this search in my recycleView item, so it call so frequently.
Thanks
I don't really get what is your real intent, but if your task is to search by id often, I would use
LongSparseArray<String> idsToNames; // or LongSparseArray<Model>
Which will map primitive long to Strings in a more memory-efficient way than Map and will have a better performance than ArrayList when searching.
The advantage over querying SQLite here is that you can do it in a blocking manner instead of having to query database on a background thread every time the lookup runs.
The disadvantage is that whenever data changes in SQLite, you will have to rebuild your idsToNames map. Also, if the number of entries in SQLite will eventually grow, you will end up in a large collection. So I would recommend this approach only if the updates to the database during this session will not happen, and if the data size is always predictable or fixed.
I have an android app that loads data from a server and displays it in an endless scroll in a recyclerview.
It loads 5 items per page and if you scroll down, it triggers another 5 page to load.
Each time I scroll down, robospice is triggered and the 5 items will be cached using the current page number as the cacheKey into a SQLite database through ORMlite. The array of items returned by my server will then be added onto the total list of all items which I saved in an arraylist. This total list is then passed to my recyclerview adapter, which updates the recyclerview.
Therefore:
(cacheKey/page number:1) - first 5 items
(cacheKey/page number:2) - next 5 items
(cacheKey/page number:3) - next 5 items
Now I can also delete items on my android app. So therefore, if I don't like item 4 on page 2 for example, I can swipe left and delete it.
Since I don't keep track of the pages in my arraylist (it is a total list of everything), I can't really go:
spiceManager.getFromCache() - fetches the items from cache but since I don't keep track of the page in which the item was loaded from (remember, I load from the total arraylist), I do not have the cache key. I can't tell if the 9th item was loaded from the 2 page, for example, and therefore I don't have the cache key to fetch it from the cache.
spiceManager.removeDataFromCache() - delete the data and the associated cacheKey for those 5 items but save the 5 items temporarily into a arraylist.
spiceManager.putInCache() - I would delete the item in the temporary arraylist and then put the data from the arraylist back into cache with the same cacheKey for the 4 items as 1 is now removed
What I can do however is this:
spiceManager.removeAllDataFromCache() - remove all the data from the cache / SQLite DB.
spiceManager.putInCache() - put into cache all the data excluding the item that was previously deleted and issuing out a new cache key.
What I'm worried about with this method however, is that it is highly resource intensive. Each time you delete something, the whole DB is deleted and resaved without the deleted item.
I think that if I want to add a new item dynamically to my SQLite DB, this issue would also come about so I would also have to delete the whole DB and re-add it the whole arraylist into my SQLite and then re-issue a cacheKey.
Are there any other strategies out there for what I want to do when I want to make changes to my SQLite cache?
Thanks!
In most of the Android sample codes, populating a ListView from SQLite database is done in two ways,
Prefetch data to List - Execute query, create Model objects for each row then add it to a List and close the Cursor, then populate ListView with List.
Without List and Model objects - Execute query and populate ListView by following the Cursor using moveToFirst, moveToLast, move, as required.
Now I want to know, which of the above method is more memory efficient, in Android ?
The Cursor approach is more memory efficient:
Suppose you have 1000 entries in your database and you have a ListView which can show 10 entries at the same time. If you create a list at first, you'll have to create 1000 model objects (each of which in turn consists of several objects depending on the number of columns of your table) and the listview creates additional 10 views (actually some more, depending on the layout of the list) for displaying the 10 items. Now when the user scrolls the list, in your Adapter you end up copying data from your model objects to the list item views currently in view.
On the other hand, if you use a CursorAdapter, whenever you have to fill a list item with data, you are provided with the Cursor holding exactly the data for that row and you can simply pick the data of the columns you actually need to be displayed in the list item. No need for creating the 1000 model objects.
From a code readability perspective, a model approach would be better because working with Cursors is quite low level, you'll need to know the names of the columns in the database and so on.
I think you need to use Service or at least Thread/Async so your UI thread will not be blocked. Service is better because people can go to other apps while downloading. You can use BroadcastReceiver to communicate with your running Service.
I'm relatively new to Android but I just cant google this. I have following situation:
quite large SQL db on android (need to select and load about 2000 records to ListActivity)
I use SimpleCursorAdapter so far BUT... it doesn't allow me to load data asynchronously with AsyncTask (SimpleCursorAdapter has no "add()" as e.g. ArrayAdapter does)
I know how to make it work with ArrayAdapter but then I lose the ID attribute every time the time is clicked and I want to do it the "clean" way and keep the id (not save it some place hidden)
===> For now user has to wait till all db output is parsed into GUI, it takes some time. How can I fix it to make it run faster ? I need something like SimpleCursorAdapter.add(item) or extend it but not sure ...
thnx
You should consider having some pagination mechanism, not loading everything in an ArrayAdapter but better, returning a simpleCursorAdapter with just a subset of size N of your records. When the user will reach the last row, display a button to increase N and refetch the data from your database.
I need to populate ListView with List of objects returned from my Dao object.
The items get returned after 3 seconds, obviously to much time for the user to wait...
I'm using BaseAdapter as the ListView adapter.
2 questions:
How can get rid of the 3 seconds waiting time? Should I just retrieve the entire list of objects in a seperate worker Thread and display dialog in the meanwhile? Is there any mechanism that allows me to get the first, let's say... 20 records, display them and fetch the rest of the records while the user scrolls down the list?
If I would use cursors, rather than ORMLite, the list would then query the DB as the user scrolls down the list, releasing the objects of the hidden cells and the cells themselves, and not keeping all the objects of the cursor in the memory. How can I achieve this behavior with ORMLite?
I hope I was clear enough, despite the bad English ;)
Thanks.
You might want to load the data in an AsyncTask, and display a ProgressDialog while it loads. Lot of Android apps do this.
Cannot OrmLite return a DataProvider instead of the while list? (I too wanted to look into ORM on Android but the management decided against it "Its slow", but I still badly want it)