Android architecture: Where should we hold the Cursor(s)? - android

Scenario:
public class MyApplication extends Application{...}
Three Activities, Overview, List and Map,
displaying the same data only providing different UI/UX.
Data fed into Contentprovider db and frequently updated externally by a SyncAdapter,
part of another application.
Read data from Contentprovider in to cursor.
Do cursor.setNotificationUri(),
to make the cursor listen for db/Uri changes.
Alt1. Hold the cursor in MyApplication.
Overview, List and Map then asks MyApplication for data.
On a db change MyApplication holds a reference to each Activity
and notifies them to ask for the data again from MyApplication.
Alt2. Hold one cursor in each Activity.
On a db change each Activity requeries the cursor for the data again.
Where should we hold the Cursor(s) ?

I'm facing a similar problem but not with DB and cursor but simple web request\response.
The problem u'll start facing soon enough is what ahppens when your activity dies in the midst of a request response.
I would suggest the following:
make a base activity u'll inherit
from that will contain a cursor for
the query.
make sure you have a method to fill
the currsor with data in onResume
start listening to broadcast
receiver.
when you finish a db update in the
separate thread, notify all
receivers.
when you perform on create check the
data in the DB to see if you missed
a call from the broadcast because your activity
has died.
so basically u will have a cursor in each activity, but no need to manage it by code unless you need to do something that is not standard with it. don't forget to dispose the cursor once the activity dies.

Related

How to pass SQL database data from one activity to another?

I have a simple application consisting in a contacts database (using a SQLiteDatabase class).
In my main activity layout, there is a "View Contacts" button. When pressed, I create a new activity (let's call it "ContactsActivity") in order to show a LinearLayout with the contacts data.
My question is: how can I give ContactsActivity access to the database?
Do I pass some data from the main activity (which I think is not an option)?
Do I just kind of open the database from this activity?
Do I use the same method that I used for the main activity (I mean, using a SQLiteOpenHelper and so)?
I don't know if I am giving enough information; otherwise, just ask me and I will provide any necessary info.
Thank you.

Fields of static objects become null when home button is pressed

In my app, I inject some singleton manager objects using dagger.
Suppose one of these managers, say myManager, keeps data in a list, say myList.
Also I have a BroadcastReceiver class, say myBroadcastReceiver which calls one of myManager methods, say myMethod, when it receives some particular intents.
If I open my app and wait until myList is initialized, then press home, and after that myBroadcastReceiver receives the intent and calls myMethod, myList is null (though myManager itself is not null).
I can't figure if it's a matter of android's natural behavior or if I've actually made a mistake that it happens.
I think your singleton class is getting unloaded due to low memory you need to save that list in onSaveInstanceState(Bundle outState) and retrieve the same in onCreate method
You could either implement a "save state" solution using onSaveIntanceState functionality provided by android in your activity or service or whatever component you're using
Or you can save your data locally in a file or even better a sqlite database, which could be very simple and straight forward to implement.
And by keeping your list "in memory" synch'd with the local storage, you'll never lose any data.
Simply using lazy loading, each time your list is null, fetch the data back from local storage.

Getting a reference to data collected by a Service from an Activity for visualization purposes

Hello fellow developers,
I am trying to achieve something in Android and I would like some advise on the best practice.
I have created an Activity which can start and stop a Service which collects data.
Instead of simply starting and stopping the Service, the Activity should also display the data collected by the Service.
Here in lies the problem. The data could be quite large so I would like to avoid Serializing and sending it via an Intent. Is it possible to simply get a reference to the data stored in the Service from the Activity?
Simple Example
1) Activity starts
2) Activity starts Service to collect data
3) Activity exists
4) 24 hours pass
5) Activity starts
6) Activity wants to display data collected by Service, but data is quite large.
My question again is simply this. Can the Activity get a reference to the data stored in Service or does the data have to be Serialized and sent from the Service to the Activity using an Intent?
Kind regards,
Cathal
Research android.app.Application class. Essentially you can use this for global state.
http://developer.android.com/reference/android/app/Application.html
Also, any long term data should be stored to a local database. I would try to limit the SELECT to certain number of records to reduce memory footprint.
I've heard that the Application class should not be used in this way necessarily (via Google Team). Instead you could make a separate Singleton class (For example call it "MyData") that holds a public static reference to a let's say ArrayList (For example called "list_data").
So when he activity starts it will call
MyData.list_data = new ArrayList<MyDataObj>();
Then in your Service you can add all of your data objects to this static arraylist like so:
MyData.list_data.add(new MyDataObj());
This allows you to work off of the same ArrayList without passing it around using Intents and etc. Although I would suggest doing some null checking whenevr

best way to share the same database among all activities

I am using a database that I need to access in all activities. So I created a class MyDBAdapter with all the methods open, create, getData etc...
To access the DB I see two different ways:
a. In each activity do I now write: MyDBAdapter db = new MyDBAdapter();
which means a new DBAdapter would be created in each activity. Each would open the same DB and have to close it. This also means that the same DB might be opened by several activities - is that OK? Or do I manually ensure that the DB is closed everytime I switch activities?
or
b. create only one instance of the DBAdapter in the first activity and pass it everytime to the next activity using putExtra("Task", x);
Then the DB gets only opened and closed once in the very first activity.
Which one is a better approach?
Thanks very much.
I prefer content provider to share data among activities.
Even though its mainly aimed to share among applications, It can be used inside our single app.
If we use content provider, there is no worries of closing and locking of db.
Content providers implement a common interface for querying the provider and returning results — as well as for adding, altering, and deleting data.
It's an interface that clients use indirectly, most generally through ContentResolver objects. You get a ContentResolver by calling getContentResolver()
Check this Simple Content Provider for db operations
Generally you have to close the database, right after you finish working with it (manually call db.close()). This mean that if you use your database in multiple activities, you have to close it every time after you have done using it. That said, it's up to you if you will make calls MyDBAdapter db = new MyDBAdapter(); in every activity or you will make a static reference to it. After all, if you have some local variable MyDBAdapter db in some code block, it will be garbage collected at some point.
Also generally speaking, you don't want your database operations in your Activities, because this way they will be executed on the UI Thread, blocking it, until they finish their db operation. You might want to use AsyncTask for your db operations which will create a separate Thread for db operations (and handle it for you). Here's a great tutorial on using AsyncTasks.

Sharing data between services and activities

I have a ListView with a custom ArrayAdapter, that shows orders from an ArrayList. These orders are supposed to be synced with my server. There I have an API, which I am requesting for new orders, and if there are any, I get an XML of the order back. What is the best approach to dynamically update the listView? I do not want to use SQLite to store the orders, because only last ten are supposed to be displayed. With a ContentProvider I am not able to store my custom Order object. And if I wrap the ArrayList into a singleton class and use it in the service as well as in the Activity class for the ArrayAdapter, the ListView is not dynamically updated (probably, because the arrayAdapter makes a copy of the arraylist?). Thank you very much.
Filip
use Intent or Bundle
i'm no sure what you mean regarding the ArrayAdapter not being updated, but i can give you a solution we used in my company.
I have a DataMaanger which is a bridge between the Activities and the Networking or SQLite.
The dataMaanger keeps it's data in memory so it's not in DB or on disk. the disadvantage of it is if your app gets killed for lack of memory and reconstructs itself, the dataManager will be empty, which leaves you with two options, either on every Activitie's death or you main task's activities death you serialize your DataManager's data, or if you are not dependant on any previous data, just make arequest again and update the data manager.
I use broadcasts to notify my activities.
To get an access to the DataManager i don't use a sigletone. i use the Application object, you can extend it and in the Manifest.xml give it's name in the tag, then it will be used instead of the regualr Application object.
You can access it later by using getApplication() method in Activity class.

Categories

Resources