Activity, Service and what kind of communication between? - android

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.

Related

Accessing a Bluetooth "ConnectedThread" from various activities

I have created a BluetoothManager much like the one in this example. This object is instantiated in a connection activity, reached from the main acitivty by clicking on a "Connect" button, which provides a ListView of selectable devices. Works great so far.
I am now connected and have a BluetoothManager.ConnectedThread running and the streams set up. I would now like to be able to send Bluetooth data from/to various other activities when they are running. For example, I will want to chart realtime values when the charting activity is running.
As far as I can tell, the pushing of the data out from the ConnectedThread will occur via a Handler, which is a new topic for me. What I am unclear on his how other activities might access the ConnectedThread's write() function.
First of all, even though a singleton could be a solution, android Service's are there for this purpose, since these are elements that can keep running when your UI is out. So my suggestion would be to create a sticky service an then you have two options:
Handle data using a handler between the activity and the Service. Maybe if you are not too familiar with the Handler api this will take some time to you. In this example of the official documentation you can also check how to use the handler.
Create a bound service, to which you can bind from the activities and send some data when required. Here you have the official information about bound services.
You can have a look to this tutorial to get more information about handlers.

Why to use bound (not-started) services within the application process?

As everyone might know, there are two primary types of services in Android: started and bound (I'm not counting started and bound services, as they're mostly the same as just started services).
You can find tons of tutorials on how to use bound services or how to bind to started service, but there are actually no answer on why would anyone use bound (not-started) services within the application process (in other words - without IPC)?
Is there any (hidden?) profit from using bound service (let's say for some sort of processing) over using standard threading tools (AsyncTaks, Executors, plain threads)? Would it worth boilerplate code for connection of such service?
Some context
Question appeared after digging through sources of Google Camera. They're creating a bound (once again - not-started) service for saving images. What is the point? Why not just used some Executor? Am I missing something important?
If that is a bound service, then there is no way it would help to persist saving progress while device configuration is changing (i.e. device is rotated). So I see no advantages.
Started Service is useful in case where there is need for no or very limited (one-way) interaction between starting component i.e. Activity or BroadcastReceiver, and the started service. For instance, a fire-and-forget background download. You give the downloader service a URL, start the service and forget all about it. The only way the downloader service ever interacts with the user is using Notifications. The Activity might as well go on the backstack in the meantime, you don't care. Note that in this case, the service is serving the Activity which started it, and there is no requirement for it to be available generically to other Activities.
On the other hand, bound service is a more generic service or one that needs to serve multiple activities, and more over, needs multiple bidirectional interactions i.e. Activity sends a message to Service, then Service sends a message back to Activity and so on. Consider the example of background music player service, where you pass the music file or remote stream URI/URL to the service, then another activity could change the volume or switch to another track etc. A message back from service to activity could be that the mp3 file is incomplete or corrupted, or a track completed message.
In fact, I came to this question looking for the answer to this exact question, but found the answer quite satisfactorily and complete in the link provided by #SagarPikhwal. Admittedly, I'm a newbie as far as Android programming is concerned, so the above is all as per what I understood !
Edit:
Realized that I didn't answer (to the best of my abilities), the other part of the question about the code you saw for Google Camera. I think the reason why they create a bound service is because Camera is a common shared resource, and there could be multiple users of that system resource simultaneously. The activity using the camera service to capture an image or video is not the exclusive user. The Google Camera application is yet another user of the camera hardware, while there could others, and all of them served by the bound-service.

Android share location service between multiple map activities

I'm writing an application with 3 mapactivities, and i've implemended a local service(like google tutorial) that recives update from location manager, to share location data from gps between these activities.
Now i want to put every activity in separated process to follow google's suggestion.
So my question is how I have to proced??
Implement and AIDL interface for remote services or register every mapactivity to location listener??
Thanks for answers and sorry for my bad english :P
If it's just a single application that needs location information, then using a remote service and AIDL is an unnecessary complication. The easiest way would be to have a local service with which the activities can bind, then have the service use sendBroadcast() to send location information. The activities can then register a BroadcastReceiver to pick up this data.
First the rationale:
That quote in the Javadoc is a bit... weird. If you understand "running" as being between onResume() and onPause(), then normally two Activities belonging to the same Application cannot "run simultaneously". You would probably have to mess with the Application class or the OS itself to have it behave otherwise.
To wit, I'm actually developing an app at the moment that uses several MapActivity subclasses and haven't encountered any problems so far (i.e. 40+h of development and testing, both on emulators and a device).
Therefore I would suggest:
Try to implement your app as a single-process activity with a local service and just run with it.
If you don't want to do that (can't blame you ;) ), or you encounter any problems, I would suggest starting out with a MapView, perhaps encapsulated within a Fragment. Here's a discussion to get you started.
In short, due to Android's practical fragmentation, keeping your Activities in one process and commiting more time by starting with a more bare-bones implementation will be a safer, ultimately less time-consuming and probably more efficient approach than artificially splitting your app and potentially gritting your teeth on the IPC. At least in my opinion.
After some research i think the best way is to implement IPC with a messenger like described in Android doc http://developer.android.com/guide/topics/fundamentals/bound-services.html#Messenger.. I'll test this solution an report here the result..
Best tutorial is http://developer.android.com/reference/android/app/Service.html#RemoteMessengerServiceSample where is implemented a 2 way communication from client and service..

Proper use of Android Services with RESTful API

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.

Android service-to-activity communication performance

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.

Categories

Resources