The efficiency of Parcelable vs Reading from the database - android

I have a fragment that lists "Semesters" in the following way: It accesses the database, generates an array that is then translated into views via a ListAdapter.
In that fragment there is also an add button that opens a new activity, wherein the user can create a new semester that is also being inserted into the database in the same activity.
After creating a semester I obviously would like to show it when the user goes back to the list.
For that I have 2 options:
Send the created Semester back as an object to the fragment. The problem is that it requires me to implement the Parcelable interface on most of my classes as they are nested, which would be really tedious.
Make the list re-read the semesters from the database and recreate the view from scratch.
My question is; which way would be faster and more efficient?
Databases could get big overtime, but same for parcel objects, especially when they are nested and there are Lists of custom objects and such, which makes this decision much more critical.

Parcels are super fast. It's essentially binary packed data and it's really memory and CPU efficient.
That said, it really depends on the size of the database. If it's relatively small (say, under 100 rows returned in the list query), I'd just requery it in onStart or onRestart. Makes everything much easier and more consistent. If that query takes noticeable time when returning to the list, I'd send it in the Intent.
Don't optimize (by e.g. making everything Parcelable) without being sure the database access is the bottleneck.

Related

Android, performance of transferring data between activities

Which one of two ways below has better performance for transferring data between activities?
Activity1: putExtra("id" , customerId)
Activity2: Select on the table and fill Customer object
Activity1: putExtra("customer", customer)
Activity2: Customer customer = (Customer)getIntent().getExtras().getSerialaizable("customer");
I mean send a unique item (like id) to the next activity and then select it from data base OR send the whole object to the next activity and cast it?
Obviously first way. You just send the ID of the object and then read it from the database in second Activity. The other way involves serialization/deserialization which costs CPU-cycles. Even using Parcelable will still use significant CPU-cycles.
On the other hand, I doubt that you would notice any performance penalties unless you are doing this for a bazillion objects. Do whatever is more straightforward and easier to understand/maintain.
Serializable is not recommended in android, check parcelable it's faster.
Serialization vs DB depends on object complicity, only profiling can show the picture, but for a one object it's neglectable.
The fastest way would be to store object in memory and share through singleton.

Android: efficiency of CursorLoader-swapCursor vs ArrayList-notifyDataSetChanged?

I have a list which usually contains < 100 entries. Sometimes 200-1000 entries. Occasionally it can contain many more such as 20000 entries.
Data is queried from a few SQLiteDatabase tables.
I load and display the data in a ListView.
I do various reads/writes in other app logic such as in a service etc.
I do operations such as: move some items around, to beginning or end of the list, modify their content, delete them, add new ones etc. - and save changes in the DB.
For the ListView I call mAdapter.notifyDataSetChanged().
I consider implementing a Loader (SQLite query loader) to use Loaders. The loader will observe data changes, re-run the query and I would use mAdaptor.swapCursor() to use the new Cursor.
My question is: while both methods would be asynchronous, which one of the above would be more efficient? (shorter loading time etc)?
It's my own question too, but I think based on my information that:
Querying the database reads from file-system which is much slower than RAM (You can visit this link)
Adapter has some more efficient methods for notifying dataset changes like notifyItemRangeIserted() and so, and the ArrayList will reside in RAM as your application resides.
So I conclude that caching data in memory will be faster but you absolutely should be careful about heap size and memory leak!

How to load data to make them visible in an ActivityList?

I'm relatively new to Android and have the following question. I have a local DB on the device from which I want to display the content in an ActivityList. Let's say there is a table "person" on the DB containing general information like "name, surname etc."
Every row in the table should be displayed as an item within the ActivityList.
I know that there exists a sort of Adapter with which I can directly fill the ActivityList with my table data, but is this the way to do it?
Isn't it better to load all the data at startup and then hold them for the entire session and pass the data from one activity to another(or make them static..) if necessary, instead of loading the data every time I change to another Activity?
If I would have a normal Java application I would load the Data at startup and then just work with the loaded objects (at least for reasonable data sets).
Doesn't it make sense for an Android App too?
I will up-rate every answer that makes sense to me.
Thanks!
Slash
I would have a look at the ContentProvider.
You can use it to query your database and then show the content in the ListView using a CursorAdapter.
You need to use an Adapter if you want to work with ListView. So, that is a must. And you can set the Adapter data from your Activity.
As for the "sense" question, it probably makes sense. But as always it depends on a few things:
Will this data be used through out the application? Then it absolutely makes sense to load it once and use it everywhere. How you do that is up to your needs, static access or passing the data, all should work.
And DB access is always expensive. And if you have lots of rows, the loading process from the database can be extremely slow. So, again, load it once and use it everywhere is a good plan.
But be careful about blocking the UI thread when you load this data. You should never access DB from your UI thread. Instead use a worker thread or AsyncTask.

Where should this code live - in my Activity or my Adapter?

I'm looking for guidance as to how to modularize my code. I have an activity and a listAdapter and they are getting pretty complex. I'm not sure what code should live where and how much knowledge each of these 2 classes should have of each other. How do you decide whether to put code in an activity or its adapter? And what patterns do you use to keep these classes as lean as possible?
Your description is too generic, so I cannot give you an exact answer (would be useful to explain why they are getting bigger and bigger, what is the extra code good for).
But generically speaking, just think about what each class supposed to do. The "Activity" (as I see it), is a main controller, it "knows everybody", and it connects the other components together (the ListView with the list adapter). The list adapter's purpose is simply to map data to views. If they are getting bigger, extract new (utility) classes.
For example assume a big part of the code in ListAdapter formats timestamps (eg. takes timestamp as long value, and based on current time creates a string like "2 hours ago"). Then it makes sense to create a new utility class called TimeFormat (with a constructor which takes a context, you'll need it later to fetch string resources). Then the ListAdapter will create an instance of this class.
Another example would be data saving. In that case you could create a class called "Model" or "Document" (again with a constructor taking a "Context" instance). It would be responsible (for example) to load the data by parsin XML files, and to save the data by generating XML files. In this case this class would be instantiated by the activity.
Also note that the ListAdapter should really do what it supposed to do: create/setup views based on data. It should never depend on other views (in other views it should work with any ListView in any layout file). So if you have "findViewById" call, which access a view outside of the ListView (or the ListView itself), then that code should be moved to the activity.
Also, when in doubt you can try to find an open source application, which is relatively mature, and does something similarn (and see how that is solving the problem).
Per the adapater documentation in android
An Adapter object acts as a bridge between an AdapterView and the underlying data for that view. The Adapter provides access to the data items. The Adapter is also responsible for making a View for each item in the data set.
So if your code has to do with getting the data to display or creating the views, then it goes in the adapter. Everything else goes in the Activity or else where. If you're spending a lot of code retrieving the information you want to display, consider using some sort of AsyncTaskLoader class. Note that loader classes can be accessed from API Levels less than 3.0 using the android compatibility package.

Android AsyncTask - One SubClass Per Database Operation?

I have an activity for initialising a game, that does multiple selects and inserts from a number of SQLite tables.
I'm trying to understand AsyncTask, but, from all the examples I've read so far, I'm wondering if I am going to have to subclass AsyncTask for every single different data operation I need to do?
For example, my NewGame Activity does the following:
1) Insert new player record into PLAYER table
2) Insert new player's pet record into PET table
3) Select cursor of n records from INVENTORY
4) Insert array of ranomly chosen inventory items into PLAYER_OWNED table
5) ....more things of a similar nature
There are going to be a few more selects and inserts for various things too, so having an individual subclass for each one is going to get crazy. Not to mention that there will be about 8 activities for this game, all relying heavily on database reads and writes.
So, basically, how do I best use AsyncTask to carry out a number of different SQLite operations?
You can pass parameters to a AsyncTask, even more, if you use nested clases, you can use global variables from inside the AsyncTask class, by using one of the above or both mentioned aids you should be able to use the same class and have it do diferent things depending on the parameter you pass. I see no real need to define multiple AsyncTasks.
You will need to define a AsyncTask in every activity.
I wrote need, because you really dont have to, but its comfortable to do it this way, and its easy to read/write code, as the AsyncTask is asociated to the activity only. This is of course suposing you use nested clases, I see no point in writing a separate class file just for an AsyncTask.

Categories

Resources