Android ==> Service question? - android

I have a service running on my android application, the service is a socket class that has to run through the whole application, i create it when my first activity loads.
How can i get an instance of this socket class so that i can call a function in this class.
For example
//how can i get an instance of the running service?
MyService s = getService();
s.writeDataToServer("hello");

There's two ways you can go about doing this depending on if you want to keep the socket open when the user isn't actively using your UI.
The first is a LocalService it's the same as a regular Service except it runs in the same process as your Activitys UI thread and therefore you can gain a direct reference to it. This is a much lighter method of creating and using a Service than using AIDL. I only recommend using AIDL if you wish to create an out-of-process service that needs to be accessed either by different processes in your application or in different applications. This is most likely not what you need. The LocalService method will allow you to keep the service running in the background and in turn keep the socket open even when the UI isn't in use.
If you don't have the requirement of keeping the socket open and only wish to have access to it from multiple Activitys then you can extend the Application class and register it in your manifest. It allows you to manage global application state. You can put the socket creation and management functions into that class and then provide methods for your various Activitys to gain access to it. The Application class dies when the process dies so it is not suitable for keeping a socket open for long periods of time or during times when the user is not actively using your application.
There is the built in Activity#getApplication() method that helps with this process. You can specify your custom Application class in the AndroidManifest.xml via the android:name attribute.

The Android Interface Definition Language (AIDL) is the correct way to connect to a service.
Check out http://developer.android.com/guide/developing/tools/aidl.html
For information how to communicate with a service.

Check out Intents and the bindService method.

Related

Bound Service vs Unbound + singleton for communication

I have a service, I need to communicate to with it (one service - many fragments/activities). There are two options for this:
Have a singleton that controls the service - starts it and then binds to it (using the app context)
Have a singleton that controls the service - starts it, the service when ready registers back as a delegate to the singleton (in a WeakReference)
Solution no 2 seems simpler to me, but whenever I read about communication with services there is the concept of the bound service.
Is there any benefit of having a bound service instead of the service registering itself as a delegate (and unregistering with onDestroy)?
Edit 1: The service is to keep the communication alive, it's expensive to set up a new communication channel. Even if no one requested any data it should keep the channel alive (heartbeat).
The service is foreground, it should run even if the activity that requested the data gets killed by the system. The next time it is created the data will be there.
The data requested by one screen might be useful for some other (therefore has to be stored in a singleton).
Bound and unbound services are both usable patterns and you should pick whatever pattern is better for you use case.
You should pick bound service if you want your service to have the same lifecycle as the components that bind to it. If you need an independent service use an unbound version.
The only benefit of one approach versus another is the simplicity of implementation.
In you case, I think you need the service only while there are running activities and fragments, then the easiest way, in my opinion, would be to make a bound service and make every activity bind to it. With that, you'll get a simple communication interface between you activities (and fragments, since they have access to containing activity) and your service.
The benefits of this approach are:
the service will stop itself if all activities unbind and start itself when first activity binds to it.
you won't need to track all running activities in the singleton and manually unbind
you won't need to maintain a singleton manager, less code -> less bugs
sometimes onDestroy can be skipped by the system and you can leak the service with the 2 approach.
Since you need your service to be running the correct option will be to use a started service and make each activity bind to it when needed. It's a common pattern.
Started service will run until you explicitly stop it or it stops itself, you can have a singleton manager that will be responsible for that.
But at the same time you can communicate with the service from your activity using binding.
So basically comparing with the first suggested approach, you'll need some instance that will start and stop the service, but the communication between activities and service will be the same - using binding.
Yes, using a bound service in Android is a much better option when communicating with Views like Activities/Fragments. This is because of the following reasons,
It runs synchronously.
You can have more control on the service data when to show on UI thread of the view. You can choose when to call it in async/sync way.
LocalBroadcastManager only runs Asynchronously.

Using a singleton to talk to an Android Service

My Android app runs a service instance that is not accessible from other apps. I know that the service runs in the same process the app's Activity, because I can read and write to a static variable on the Service class from the activity and the Service sees the changes.
Communicating with the service via static variables/methods (or more properly singletons), is much, much simpler than communicating with it using a Handler or an Intent, which requires making all passed parameters Parcelable. It seems like these two communication methods are really designed for services running in a separate process, and are unnecessary overhead for an in-process service.
It seems like I must be missing something big. What is wrong with using a singleton to talk to a service if you know it is local to your app?
Communicating between a Service and an Activity is one of the main reasons to use a bound service: you can build a Binder class that defines the interface between your Service and Activity and pass any objects you want between them without having to worry about parcelling them (as binders require both to be on the same process).

Singleton or Service for socket connection

I'm new to Android development, i'm trying to port an IOS app to Android. Basically my App need to communicate with a server in real time with socket IO. It connect to the server and then handle the various message until the server finish to process the request.
In my IOS app i use a Singleton pattern to send the requests to my websocket server, and i use the same instance to delegate the server response.
In Android i was going to use the same pattern, with a callback object in my activity to redirect the user after getting a server response.
I need my app to keep the socket connection open until we got the right status from the server, even if the app goes in background.
Some people recommend using Service with Broadcast receiver instead of Singleton. Is it the best thing to do in my case ?
Using a Service is exactly what I have done for very similar purposes (doing socket communication for Bluetooth and TCP/IP applications) and think you'll certainly want to be using a Service if the communication should continue even when the user has closed the application.
A Service is essentially a means to run code on the UI thread (but of course you can then start off other threads within it) but without a user interface, unlike an Activity which has a UI associated with it.
If you were to try to do this in a static singleton class as you propose as an alternative, then I think the problem would be that you wouldn't have very good control over the lifecycle of it. If the user navigates away from the application, then my understanding is that it's up to the framework when it chooses to remove the process and all the static objects along with it. For this reason, if you have singleton classes populated with data and you exit your application and then later come back to the application, you may or may not find that the 'old' singleton instances are still around. For this reason, in my application (which uses a very large amount of global state) I've resorted to holding my singletons' actual instances in an extension of the .Application class, to (hopefully) better control their lifecycle.
With a Service you have a well-defined lifecycle with appropriate lifecycle callbacks (onCreate(), onDestroy(), etc.) just as you do with an Activity.
Yes, definitely use a Service. From the docs:
A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user
While using a singleton might work for a while, your application would be prone to being killed by the operating system when it goes into the background unless you have a Service. If you're more comfortable with the singleton pattern, you could implement it in a singleton and then just tie it to a Service simply to maintain its lifecycle, but that seems more of a mess than it's worth. Note that you shouldn't do network operations on the UI thread and by default a Service runs on the UI thread. You'll need to spin up another thread to do your work.
I don't see anything in your post that demands a BroadcastReceiver, though perhaps there may be some network related broadcast intents that might be useful like android.net.ConnectivityManager.CONNECTIVITY_ACTION.

How to best implement Two Activities sharing One Service (w. Bluetooth Connection)?

Right now the main Activity (Act. A) starts a Service which holds the Bluetooth Connection.
(It binds the Service)
The Service is a modified version of BluetoothChatService (Android BluetoothChat Sample)...
... modified with an added Messenger and Handler in accordance with MessengerService (Android Remote Messenger Sample)
Activity A makes sure that the Bluetooth is connected to an external device, and later starts another activity (Act. B).
The problem is to get the Service to keep running and serve the Bluetooth Connection to the new activity smoothly. I don't know how to:
Make sure that the Service is not restarted or reinstanced, when it switches from activity A to B
Make sure that the messenging functionality works as desired (from the currently active activity)
Do I need to rebind the Service to the new activity, and how do I assure that the BT connection is not lost (due to other instance of Service)?
Or do i need to pass along the Messenger object to the new activity to communicate with the alread instantiated Service. If so, how do I do that best?
Very thankful for answers!
Make the service "sticky" so that it will continue to run. And create a base Activity class for your 2 activities. The base Activity class can handle all the common functionality of binding with the service and providing the proper communication. I would definitely recommend unbinding your service when the activities pause and re binding them in the activities when they resume. But this can be done once in the common base class activity.
Binding to the service should only start it if it is not already running and if you bind/unbind in Resume/Pause you should have only one active connection to the service at any given time.
You either subclass Application and store information in there (see here), or you could make your "service" a singleton, so it has a static member of its own type that you initialize only if it's null.
This is an old question, but I ran across this situation today and came up with a solution that works based on the other responses. Since I couldn't find a working implementation, I will post it up for others who may be curious. I created a "sticky service" and then a ServiceManager class that is responsible for managing the life-cycle and binding for the Service. Then I put the ServiceManager class into a sub-class of Application so the Activities can access it as a scoped global. It works well. Source is available on GitHub.

Binding to Service from Activity or starting service in different process?

I want to do Bluetooth connection in Service. And there needs to be interaction between Activities and Services. The service should be started as soon as the app is started and should be able to communicate with UI Activities on certain situations.
What should be the appropriate way of doing it? If I bind the service from only one Activity then that service will be communicating only with that Activity. So, do I need to take AIDL based approach or is there any other way out for this?
Otherwise, can I have a class that extends Application class and then start the service from there and bind the Application class instead?
This is quite a broad question, so I'll answer as best as I can. From what I know of services, multiple activities can bind a single service, all having access to it. Only once all activities that bound the service end their connections (by unbinding), does the service actually stop.
The android documentation on services tells us:
... the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE flag. Once neither of these situations hold, the service's onDestroy() method is called and the service is effectively terminated
So my recommendation would be to bind the service from all activities that need to communicate with it. When binding with a service an IBinder is returned, which you can use to communicate with the service. Again according to the Android documentation on services:
Usually the IBinder returned is for a complex interface that has been written in aidl.
Although if you only need to perform simple communication with the service, you could use the Messenger class instead of writing full AIDL files. A sample of this can be found here.
Hope this answers your question!
You could bind directly to the Service as the above answer states, however there is no need for Messengers. Your service will be running in the same process as your activity 99.9% of the time. Messengers are designed for inter-process communication (IPC). Also no need for AIDL - that was designed for advanced IPC.
Instead, you should use: BroadcastReceivers and Intents. This is what they were designed for (communication between components in an app).

Categories

Resources