Android AsyncTask - One SubClass Per Database Operation? - android

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.

Related

What is the best way to use threading on a sorting algorithm, that when completed, creates a new activity and gives its data to the new activity?

I will start this by saying that on iOS this algorithm takes, on average, <2 seconds to complete and given a simpler, more specific input that is the same between how I test it on iOS vs. Android it takes 0.09 seconds and 2.5 seconds respectively, and the Android version simply quits on me, no idea if that would be significantly longer. (The test data gives the sorting algorithm a relatively simple task)
More specifically, I have a HashMap (Using an NSMutableDictionary on iOS) that maps a unique key(Its a string of only integers called its course. For example: "12345") used to get specific sections under a course title. The hash map knows what course a specific section falls under because each section has a value "Course". Once they are retrieved these section objects are compared, to see if they can fit into a schedule together based on user input and their "timeBegin", "timeEnd", and "days" values.
For Example: If I asked for schedules with only the Course ABC1234(There are 50 different time slots or "sections" under that course title) and DEF5678(50 sections) it will iterate through the Hashmap to find every section that falls under those two courses. Then it will sort them into schedules of two classes each(one ABC1234 and one DEF5678) If no two courses have a conflict then a total of 2500(50*50) schedules are possible.
These "schedules" (Stored in ArrayLists since the number of user inputs varies from 1-8 and possible number of results varies from 1-100,000. The group of all schedules is a double ArrayList that looks like this ArrayList>. On iOS I use NSMutableArray) are then fed into the intent that is the next Activity. This Activity (Fragment techincally?) will be a pager that allows the user to scroll through the different combinations.
I copied the method of search and sort exactly as it is in iOS(This may not be the right thing to do since the languages and data structures may be fundamentally different) and it works correctly with small output but when it gets too large it can't handle it.
So is multithreading the answer? Should I use something other than a HashMap? Something other than ArrayLists? I only assume multithreading because the errors indicate that too much is being done on the main thread. I've also read that there is a limit to the size of data passed using Intents but I have no idea.
If I was unclear on anything feel free to ask for clarification. Also, I've been doing Android for ~2 weeks so I may completely off track but hopefully not, this is a fully functional and complete app in the iTunes Store already so I don't think I'm that far off. Thanks!
1) I think you should go with AsynTask of Android .The way it handle the View into `UI
threadandBackground threadfor operations (Like Sorting` ) is sufficient enough to help
you to get the Data Processed into Background thread And on Processing you can get the
Content on UI Thread.
Follow This ShorHand Example for This:
Example to Use Asyntask
2) Example(How to Proceed):
a) define your view into onPreExecute()
b) Do your Background Operation into doInBackground()
c) Get the Result into onPostExceute() and call the content for New Activty
Hope this could help...
I think it's better for you to use TreeMap instead of HashMap, which sorts data automatically everytime you mutate it. Therefore you won't have to sort your data before start another activity, you just pass it and that's all.
Also for using it you have to implement Comparable interface in your class which represents value of Map.
You can also read about TreeMap class there:
http://docs.oracle.com/javase/7/docs/api/java/util/TreeMap.html

The efficiency of Parcelable vs Reading from the database

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.

CursorLoader with Cursor accsss inside a loop

I'm building a ListView, and each item in the ListView has data from several different Cursors. I've got an object which holds all the data for each item in the ListView. I'm using an ArrayList of these objects to populate the ListView.
The way I'm implementing it now, I first get a Cursor to all the rows in ContentProvider A. I loop through this cursor, adding three of it's fields to each object in the ArrayList. On each iteration of this loop, a new cursor is created to pull a field from ContentProvider B based on a field in ContentProvider A. This field is used to pull another field in ContentProvider C. So, essentially, there's lot's of Cursors being created, and the queries of subsequent Cursors are dependent on data from previous Cursors.
From what I understand, it is ideal to use CursorLoaders and LoaderManager to generate the Cursors in a separate thread and manage their life cycle correctly. I'm not sure how to translate this approach, or if there is in fact a better approach that minimizes the number of Cursors in the first place.
I think a simple CursorLoader is not the right solution in this case. I think you might have two possibilities:
Use a CursorLoader for the first Cursor and use CursorLoader-chaining within your ListAdapter's getView() method. With CursorLoader-chaining I mean calling initLoader() in your onLoadfinished() method.
Use an AsyncTaskLoader and create within your AsyncTask the object tree you need.
Of these two solutions I think the second is probably the better one - unless the list is very long. This is one area where ContentProviders fall short. You basically have to query n+1 (in your case n+2) times where one join should suffice.
If your list is very long, the second approach is not usable, your AsyncTask would take too long for users to accept it.
Should you ever hear of (or find yourself) of a better solution, please ping me here.

Loading a BIG SQLiteDatabase in a ListActivity

I'm working on an Android project I need to finish very fast.
One of the app's features is loading a SQLite database content and listing it in a ListView inside a ListActivity.
The database contains a few tables, among which 2 are very large.
Each item in the database has many columns, out of which I need to display at least 2 (Name, Price), although preferably is 3.
This might seem a pretty easy task, as all I need to do in this part of the app is read a database and list it. I did this without any problems, testing the app versus a small sample database.
In my FIRST version, I used a Cursor to get the query, then an ArrayAdapter as the list's adapter, and after the query I simply loop the cursor from start to end, and for each position I add the Cursor's content to the adapter.
The onItemClickListener queries the database again versus other parameters (basically I open categories) so it clears the adapter, then loops the Cursor and adds its content to the adapter all over again.
The app worked like a charm, but when I used a real-life, big database (>300MB) I suddenly got my app taking very long to display the contents, and sometimes even blocking.
So I did some research and started using a SimpleCursorAdapter that automatically links the contents of a Cursor to the ListView using the usual parameters (String[] from, int[] to etc., where I used android.R.layout.simple_list_item_2 and android.R.id.text1 and text2).
Problem is, is doesn't change much the time to load.
I've came across some suggested solutions on different web sites and tutorials, most of them using, in one way or another, the AsyncTask class. I tried implementing this manually myself but it's hard to keep track of multiple threads and I failed.
Tutorials keep telling how to do this with content providers, but I found nothing clear bout my specific situation: very big SQLite database -> read to ListView.
Now my head is filled in with notions like LoaderManager, LoaderAdapter etc, all mixed up and confused in my head.
Can anybody please provide me a complete, nice, clean solution to do this "simple" task?
Again: I want to read a BIG SQLiteDatabase and display it in a ListView. I want the app NOT to block.
I need a class that has a member function that takes as parameter a query and the ListActivity's context and takes itself care of displaying the result of the query in the view.
Please don't provide me abstract answers. I'm running out of time and I'm very confused right now and I need a clean complete solution.
You're my only hope.
If you query such large database it will take tym, you need to find a smart way,
Like limit you database query to get first 10 or 30 items and then maintain,once last item is reached query rest 30 items and bind them
Refer this tutorial, it will teach you how to add data dynamically in a list view
http://p-xr.com/android-tutorial-dynamicaly-load-more-items-to-the-listview-never-ending-list/
The above list has expired chk this
http://mobile.dzone.com/news/android-tutorial-dynamicaly
If you query large database it will take time to fetch data and show it on List View. So it is better to populate data at run time. You can use Lazy Adapter concept to load data . This link1 may be useful for You.
Thanks
you can also use :
public class TodosOverviewActivity extends ListActivity implements
LoaderManager.LoaderCallbacks<Cursor>
check this link for more details.

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.

Categories

Resources