Firstly I may say that I know there are a lot of resources dealing with the communication between services and activities, I have also read the service-related part of the android developer guide. However, I'm still not sure about the best approach in my case.
When it comes to the communication between services and other components (like activities), bound services are described as the solution in most cases. But from my unterstanding, the use of a bound service always results in a request/response-model - an activity invokes a method on the service (request) and gets a return value (response). The android dev guide calls this a client/server-model.
In my scenario, a service generates a list of POJOs on a regular basis, but not exactly predictable (let's say every 1.5 - 2 seconds). Every time this happens, the list should be transferred to an activity in order to display it on the screen. In my opinion, a bound service is not the solution here, since my scenario does not match the request/response-model. In fact, the activity is passive and not really aware of the service. Of course I could use a polling strategy together with a bound service, but imho this is not the best approach in my case.
What would you recommend? I found solutions using a BroadcastReceiver in the activity (the service acts as sender), is this the only way or are there any other approaches? Or do I have a wrong unterstanding of bound services and they are not limited to request/response-scenarios?
edit:
As I already mentioned, a new list (java.util) is generated every 1.5-2 seconds by the service and should immediately passed to the activity. Such a list contains 20-25 POJOs that represent model objects; they contain 5 Strings and 3 integers each.
Just to give you a feeling of the complexity.
Is the BroadcastReceiver adequate for this amount of data and frequency?
I would say, BroadcastReceiver is the best approach for this as compare to other options like handler, it would be create problem when large amount of calls would be occur. BroadcastReceiver will work fine because the flow of its working. I have worked with this, and I have got good result.
Related
I need a shared list of computers made available to all my app's activities. The list of computers needs to be upated by two background tasks of some kind, one that blocks on a socket waiting to receive data, and another task that periodically purges computers from the list. What is the proper Android way of doing this to avoid running into activity lifecycle problems? Specifically,
Can/should I use a singleton to maintain and expose the list to the activities and background tasks? (I'm familiar with thread synchronization issues and am prepared to deal with that.)
Can/should I use the IntentService class (two separate instances for the work I need to carry out) or is there a better way? Do I need to use a BroadcastReceiver in that case or could I still store the list in some common place, like a singleton?
How do I avoid keeping my services running when my application is put in the background?
Updated answer for updated question
You can use a Singleton if you don't have a problem with losing your data when your app get's killed (e.g. when you can rebuild the data on restart). In this case you should check that all your components run in the same process (which is default).
You should not use IntentService for intra-app-communication, however bound Services might be an option here
If you bind services from an Activity and unbind them in onPause, they get automatically stopped (if there are no other bound contexts and they weren't started with startService)
If you think your tasks are too complex to accomplish in the same Service, I would recommend two Services bound by an Activity and backed by a ContentProvider which e.g. can be backed by a database.
Old answer
The issues you expierenced might be a problem of Thread-safety (or the lack of it)
Two Intent Services just to share data within an application is definetly way over the target
A broadcast is the right way to notify components of a change
You might want to take a look at Content Providers
Another solution might be a service, which can be bound by all your other components
You can use Database to maintain the UDP packets with timestamp.
Also periodically check the last sync time from Database to check whether UDP packet is coming or not. Hope you know how to use Database.
I'm trying to develop an Android application consists of an Activity and a Service. The Activity launch a process on the Service of indefinite duration, which will be closed from Activity. Do not use then the subclass IntentService, but directly Service. Controlled by onStartCommand and OnDestroy.
I obviously need to pass information from the Activity to the Service: the status of the Service and some strings.
I tried to use LocalBrodcastManager, but when turning the devices or when the activity goes in state onPause, the message will lost. I tried to follow several examples, but with little success. This in particular I could not complete it because of some missing information, evidently deemed obvious, but which are not obvious to me: https://developer.android.com/training/run-background-service/report-status.html
I then tried to use Messenger via IBinder ( Example: Communication between Activity and Service using Messaging ), But the program seems a bit complex and I can not able to fit my needs.
What I need is to launch the service from my activity (possibly make binding automatically?, in case of Messenger use), the Service should signal the Activity to be active, then Service records some points via GPS LocationListener, writes it to a file and should point out, again the Activity, the data that is recording, the file size, etc.
What do you recommend to use to pass this information and can you provide to me some example?
I am actually in the midst of a tutorial explaining and comparing many different approaches to IPC in Android but since it's not ready and because you need an easy fix i'll recommend https://github.com/greenrobot/EventBus.
Also feel free to look in an old but still relevant example me and my friends made a while back here: https://github.com/RanNachmany/AndconLab
Goodluck.
I am writing an application that shows "Japanese Traditional Time" (JTT for short). There are several components (notification, widgets, application itself, alarms) which all use the same data - current JTT.
My current version uses a single service that does all the calculation and uses a Handler to notify everyone about "ticking", mimicking ACTION_TIME_TICK.
However with alarms I need to also have a way to translate "usual time" to JTT and vice versa. The calculations are quite CPU-heavy (it's all based on sunrises and sunsets) and thus I prefer having it all done in a single place and then cached (calculating stuff knowing sunrise and sunset times is not as heavy).
So I have several ways to do that now:
Keep it all in Service
And use binding to request the data I need. It's actually already done in one case and seems a bit cumbersome since I have to handle asynchronous responses
Move to content provider
And use content observers instead of broadcasting
Or send broadcasts from provider
Combine both ways
Use content provider to calculate the data for service which in turn will broadcast it when needed
Which would be better? Maybe something else?
Content providers are for structured data, so it doesn't really fit your use case. Not sure what you mean by 'asynchronous responses'? Calling a remote service is usually just like a local function call, it will block and return a value when done. If you have to notify multiple components a broadcast is the way to go. Explore using a LocalBroadcast if all components are in the same process (check Android support library source), or set a permission on it to make sure other apps cannot get it if you need to send a system-wide (regular) one.
I'm sticking with "just service" - I have discovered Sticky Broadcasts which actually cover the problem I had with common Broadcasts (having to request latest data from service after registering but before getting the first "tick") and that leaves me with much less cases where I need actual service connection.
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.
I can find several examples of how to build a service, but I'm having a difficult time finding a working example of how to send messages between an Activity and a Service. From what I can find, I think my options are to use Intents, AIDL, or to use the service object itself as per this question.
In my case, my activity is the only activity that will ever access the service, so a local service will do. When the activity is open, I want to see some status messages from the service, which will be coming in at up to 20 Hz. Are there any limitations on how many messages per second those communications methods will support? Basically, which method is going to be best for my situation?
Thanks.
Since your Actvity and Service are a part of the same app, then no need to use AIDL. You may simply use your Service as a local one.
The limitation is only affected by the performance of your device. There is no cap on requests per second.
Usually there is a context switch involved, that uses quite a lot of cpu (compared to other parts of the transmission), but since you use a local service you don't suffer from that. In any case, 20Hz is not a problem.
The best solution for you would be to use AIDL, and set up a callback that the service can call to report its status.
There is good example of how this is done in the APIDemos.