I am having trouble grasping the correct way to implement a centralized data access for different resources.
I want to have a single class, call it DataAccess.class that will call from both a SQLiteDatabaseHelper.class and a ServerAccess.class depending on what is appropriate when I call it's methods.
I thought extending DataAccess.class from a Service was the best approach so I can use ASyncTask for the ServerAccess.class. Now I am having doubts. The DataAccess.class needs to be accessible by most of the Activities in my Application, and I want it to stop when the Application does.
According to the google developer resources it sounds like a Service is well used for ongoing operations in the background but I am unsure how to handle the life cycle given the scope that I am trying to incorporate. Can I make the Service call startService() and stopService() internally when I use the DataAccess.class methods? Does it make sense to call it every time I access the Service or should this only happen once at the start and stop of the Application?
Thanks for the help,
I would recommend
1) Use all AsyncTask based solution because Service - Activity Communication is limited. (Unless of course you need to run something in the background) BUT I would love to hear the counterargument to this, why use a service instead.
2) Don't use just one Facade like DataAccess but make it specific to your app functions (ie sort of like System Services in Android).
3) You should use factories just like Android does to get the DataAcccess object you need. This addresses second part of where you get DataAccess object. Follow same model as getting and Android System service.
4) Use Content Providers where indicated and manage as indicated in Android docs.
Update: I think these are sort of the Axioms of a good solution. Not the whole thing. I will update as we consider this in depth.
Related
I have a two part question. Both are somewhat general.
I'm creating an app that relies heavily on communication with a server. I plan to have different classes for each repository I'll need. Is an Android service the correct pattern to use here? There may be certain situations where I'll want to cache things between activities. Will a service allow me to do this?
Assuming a service is what I want to use for this, how can I load content once the service is bound. When the user opens the app, I want to start loading content. However, binding a service isn't blocking, so I can't write the code that makes requests with the service in my onStart() right? Is there some helper class that will wait for the service to load then execute a function? I know I could put some code in my onServiceConnected() method but I'd like to stay away from coupling like that.
Hopefully that wasn't too abstract. Thanks in advance.
Yes, Service is the way to go, but a started service, not a bound one.
You could make async request methods, and the Service can broadcast the result back to your Activity.
The async request in this case is a startService(intent) with an
Intent containing the request parameters. The service would start a background thread for the operation, optimally you can use a networking library for this (for example Volley).
And the reply is a broadcast by the Service with the relevant data.
This answers the problem of caching, because the Service can decide what to return. So in case the Service does not have the requested resource, it will download (and return) it. But if the Service has the resource, then it will just simply return the cached version.
To start, you should get yourself familiar with these topics:
Started Services (for the requests)
LocalBroadcastReceiver (for the reply)
Event Bus (alternative to LocalBroadcastReceiver, for example Otto)
I don't know much about your concrete needs, but it seems like you want to implement a REST client with cache. There is a really good Google IO presentation on that here. Definately worth to watch!
1)If you need code to run even when your Activity isn't, the correct answer is a Service. If you just need to cache data, then storing it in a global static variable somewhere may be ok.
2)Your service can start a Thread or AsyncTask. These execute in parallel. onStartCommand generally launches it in this case.
As with most things, the answer to these questions are subjective at best. I would need more information then I currently have, but I'll take a vague, general stab at this...
If you need something persistently hitting your server repeatedly I would say use a service.
Where you call it is not nearly as important as how many times it needs to be called. That being said the answer is yes. If you need this data as soon as the application or activity loads, then the onCreate method is where it needs to be loaded.
My reccomendation is either A) service or B)AsyncTask.
Go with A if you have to hit the server repeatedly for data and need it in regular intervals. Otherwise go with an AsyncTask and load all the data you need into an object for storage. Then you can use it as you need and it will essentially be "cached".
The difference between the two is simply "best tool for the job". I see you use some javascript. To give a proper analogy, using a service for a server call rather than an async task, is the equivalent of using a web socket (node js) when you could of just used an ajax call. Hope this helps. Oh and PS, please don't use static variables in Android =).
I would like to have all my Activities (7 to 10 different screens) submit data to a "controller" (sorry if I'm miss using the term).
Inside said controller data would either be uploaded or saved to data for uploading when no internet.
The controller would do checks and processing such as:
Checking for valid session.
Attach other needed credentials before
upload etc.
Session/User data would be stored in a Shared Preferences file the controller has reference to.
My goal is to have Activities do nothing more than collect the data and call the appropriate method (with a data object) asynchronously. The controller would know how to process the data for uploading or saving in the database.
Would placing these methods in an extension of Application be a bad idea?
It was mentioned that depending on application size this is feasable, but there could be better solutions.
Depending on the size of your project, that would be a suitable idea. However, there are some other ways you should know before choosing the method you're actually implementing:
Using a ContentProvider for your data, an AccountAuthenticator and then sync to the server using an SyncAdapter. Advantages are a good abstraction, independence from activities and many built-in features (for example: Android executes your code without a big battery life impact). However, implementing all the stuff is quite much work at first. If you don't want to use the ContentProvider, the same technique works with a stub implementation as well, the same goes for the AccountAuthenticator.
Using a Service, probably IntentService, for your uploading needs. Advantage is that the Service has an independent lifecicle and thus is not directly related to your Activity; a Service can get restarted if it has been killed by the system. Still more work than just using some static methods.
Using a static method as you're proposing it (in your case, the Application object; not completely static, but compareable). Quite easy to implement, probably the best way if there are similar tasks in multiple activities; your AsyncTasks can send their result directly to the activitiy that started it. However not suitable for long-running tasks.
Implementing within the Activity; If code is only used once; listed for completeness only, not for your case. Basically the same as using a static method.
These are the ones that popped into my mind, there might be some others, too. Feel free to add/suggest additonal ones.
I'm currently learning to develop for Android and I'm having a somewhat hard time figuring out when and how to use services. I have already seen the numerous questions asked about very similar things, but I can't quite find the exact answer to my questions.
I have an app which talks to a restful api. I fetch several lists which I would like to cache in memory and only update if the user hits a refresh button, or certain activities are created. If a list is refreshed, sometimes several activities need to be notified, so that they update their content (if they are on screen at the time). I store the data I retrieve in value objects.
On a non-android app I would usually create a sort of dataproxy class in a singleton pattern. I could ask the dataproxy to update its data via http request, and then it would send some kind of system-wide notification as soon as the data is changed, so the interested views can all be updated. I hope this makes sense.
My question is now: How do I do this the android way? Do I bind and unbind to a dataproxy service, which I can actively ask to fetch certain data? Should I do my non-persistent caching in this service or somewhere else? Do I need AIDL, or can I just use normal objects for moving data between a service and an activity? Although I find the android dev guide pretty well written and useful, I haven't found much information on services best practice.
Thank you in advance!
How do I do this the android way?
You assume that there is a single "android way".
Do I bind and unbind to a dataproxy service, which I can actively ask to fetch certain data?
You can either bind, or send commands via startService().
Should I do my non-persistent caching in this service or somewhere else?
If you're sure that you only want it to be in RAM, I'd lean towards static data members. Make the service be the "do-er", not the store.
That being said, I'd treat this more as a synchronization pattern, with the real store being a database or directory, with a cache in RAM. Users will find this less frustrating -- under your current plan, if they are in your app, then take a phone call for a while, they'll have to have you download all the data again.
Do I need AIDL, or can I just use normal objects for moving data between a service and an activity?
If they are all in the same process, normal objects is fine via binding, or use Intent extras for the command pattern.
Now, back to:
How do I do this the android way?
Option #1: Wrap your store in a ContentProvider and use ContentObserver for changes.
Option #2: Have your service send a broadcast to your package when the data changes, so the foreground activity can find out about the change via a BroadcastReceiver registered via registerReceiver(). Other activities simply grab a fresh look at the data in onResume() -- the only one that immediately needs to know of the data change is the one the user is interacting with, if any.
Option #3: Use the binding pattern with the service, and have the foreground activity register a listener with the service. The service calls the listener when data is updated. Once again, ather activities simply grab a fresh look at the data in onResume()
Option #4: Cook up your own listener system as part of your static data members, being very very careful to avoid memory leaks (e.g., static reference to an activity or service that is destroyed, preventing its garbage collection).
There are probably other options, but this should get you started.
The Google IO session mentioned by Andrew Halloran:
http://www.google.com/events/io/2010/sessions/developing-RESTful-android-apps.html
Check out the Google I/O session videos. I implemented REST api calls the easy BUT wrong way. It wasn't until watching this Google I/O video that I understood where I went wrong. It's not as simple as putting together an AsyncTask with a HttpUrlConnection get/put call.
My Application has an Activity for the UI and a Service for background polling fun. Seems like standard fare.
Can AlarmManager trigger the Service Intent without Activity OnCreate being called?
Is there any benefit to putting the Activity & Service into different Applications? Would this create 2 apk's and make it impossible to put into Market as one app? Can you put 2 applications into one manifest somehow?
Regarding communication between the two:
-If Activity & Service are part of the same Application - can't I just store common objects (like User object) at the Application scope for the 2 to share?
-It seems like I don't even need to bother with AIDL - the two could just have weak references to each other at the Application scope as well - and they can call methods on each other that way? Or should they pub/sub each other with some kind of Observer Pattern or BroadcastListener thing?
Can AlarmManager trigger the Service Intent without Activity OnCreate being called?
Yes.
Is there any benefit to putting the Activity & Service into different Applications?
IMHO, no.
Would this create 2 apk's and make it impossible to put into Market as one app?
Yes.
Can you put 2 applications into one manifest somehow?
From a pure XML standpoint, there is room in the manifest for more than one <application> element. However, AFAIK, only one is supported.
If Activity & Service are part of the same Application - can't I just store common objects (like User object) at the Application scope for the 2 to share?
For very quick things, yes. However, bear in mind that your service may get shut down (by Android, by user, etc.), after which your process may get terminated, and your Application object goes poof. I'd use this for light caching only.
It seems like I don't even need to bother with AIDL
Correct -- that is only needed for inter-process service binding.
the two could just have weak references to each other at the Application scope as well
I wouldn't do that in a million years. Please use the platform responsibly. There are plenty of ways for activities and services to communicate yet remain loosely coupled (or, in the case of the local binding pattern, tightly-coupled in an Android-aware fashion).
Or should they pub/sub each other with some kind of Observer Pattern or BroadcastListener thing?
Something along those lines would be preferable. While the activity and the service may be co-resident in the same process at the same time, they are not designed to be directly linked to one another.
Im wondering what is the point of using a android service to do background work when you need to do a lot of things just to access any public methods or get a large chunk of data from a service such as a larger List object.
why not just use a simple POJO that does stuff in the background for you in a seperate thread if you like and gain access to its public methods without creating interfaces using AIDL, binding to a service etc etc?
seems soo much work needs to be done to access a method from a service class or is that really not the point of a service class in android?
i have developed a android service class that gets 100's of items in a xml structure from a web service who i then parse it into a POJO that is then stored in a List but i am having difficulty finding a way to send this List back to the activity that called this service.
i've read about using parcebales objects but that along with all the intent.putExtra have a size limitations so i may run into problems in the future.
i am thinking of ditching Android services and i have quickly found out why i dont like using them in the first place :(
a simple SomeBackgroundPojo backroundTask = new SomeBackgroundPojo(); backgroundTask.getData();
Seems soooo much easier than dealing with parcelables, serealizable objects, AIDL, binding etcc etc all just to achieve the two lines of code i just typed above :(
Nitpick: an object running a threaded background task ain't precisely what's usually meant by a plain old Java object.
If you don't care what happens to the work being done if its requesting Activity or Application is shut down, then by all means avoid services. One of the main points of Services is that they can stay alive when the user navigates away from an Activity: if you're only doing work to fill a UI ListView, by all means use e.g. an AsyncTask, as is discussed in this earlier question.