i'm having trouble finding a way to implement this:
I have an activity A from where i'll start 2x separate socket connections.
Afterwards i'll move to an activity B from where i'll go back and fourth with activities C and D. All 3 activities will exchange messages via the sockets.
Now from my understanding i need to create a service for each socket, but how exactly do i maintain both sockets open, without creating a new connection everytime i switch to another activity?
Also how do i keep the services running an "accept loop", prompting an action for the current activity the user is in?
thanks
You're correct that you should use a Service. A good rule of thumb is that you should use a service for any background processing that is not logically bound by the lifecycle of a single activity. (And use AsyncTask for background processing that is logically bound by the lifecycle of a single activity.)
But you don't need to create a service for each socket. You should create one service that does whatever it is you need to do with the sockets. There are a variety of ways your activities can interact with the service and pass messages or obtain references to its sockets, which you can read about in the documentation.
Related
I'm writing a Bluetooth remote control application to control my Bluetooth enabled robot, but I have a hard time understanding the workflow of an Android application. I know what I want, but it's not very easy to do. Other responses haven't been satisfactory.
Here's a rough application layout I want:
If you have a better idea of how to do this thing I'd be happy to consider.
Mainly my problem is accessing the connection thread/service (whatever the name is) from the connect method of the main activity and from the control activity, how do I pass the reference? I know that the main activity can disappear when in a sub-activity of the application, so I'd have to pass the reference by getExtra() probably, but it only takes a String variable...
One method you might like to consider is using a Bound Service. This can be made to return an IBinder interface, allowing access to the service's public methods. You can make any of your activities bind to the service and thus pass/retrieve data to/from the service.
If you need the service to communicate with the activities immediately (e.g for lost connection), then the service could use sendBroadcast to inform activities which had registered a BroadcastReceiver to listen for the intent sent in the broadcast.
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.
To begin with, this is the first Android app I'm writing, and I have very little prior Java experience. So nothing is too simple -- I could easily be missing anything "obvious".
Here's the general design I'm dealing with:
A long-lived bidirectional network connection.
Requests should go out over the network when the user interacts with the UI.
The UI should be updated when the responses to said requests come back -- asynchronously.
The app will contain multiple activities.
These activities will be focused on particular areas of functionality available, all relying upon the same underlying network connection. So I want to set up this connection no matter which activity my app starts in, and have it survive across switching to another activity in my app, but I want to shut it down when switching away from my app completely.
I think I want threads. I've got something basic working, but not well because I don't think I have them organized properly. I also am, so far, unable to pass data between the UI and network thread, so I can't get requests in nor actions for responses out. So I'd appreciate any advice.
I think I want threads.
You don't have a choice on that front. You will need a thread that listens on your socket for incoming data. Android is no different than standard Java in that respect.
I also am, so far, unable to pass data between the UI and network thread, so I can't get requests in nor actions for responses out.
Well, your thread should be managed by a Service. The network connection supports multiple activities, so no one activity should own the thread.
You will then need to decide when the network connection should exist. Since activities come and go, you will need to decide if the network connection should only exist when one of your activities is in the foreground (in which case you would likely bind to the service with bindService() from each activity), or whether there is an explicit "start" and "stop" operation that the user must do, so the connection can live after all of your activities are gone (in which case you would likely use startService() instead of bindService()).
Once you know when and how you are starting/stopping the service, you can decide how that service will communicate its results back to the various activities. There are tons of options, some better than others depending on your use case. Registered listeners, Messenger, broadcast Intents, a ContentProvider, and so on are all candidates. Any of those can be used by a background thread and can arrange to get data to the foreground activity on the main application thread. The other activities would typically refresh their data during onResume(), since there usually is no point in proactively updating them when they are not on the screen or may have even been kicked out of RAM.
IOW, "advice" is several chapters in a book or two. :-)
I would like to ask for some example, where two different activities (a button in the first activity opens a second activity), are communicating with one service (AIDL, etc.).
I've tried many different tutorials, but they are only about how to make one activity → one service.
This is probably old, but I'll try to answer it anyway...
In Android, seeing as only one Activity can bind to a Service at a time, and only one Activity can be shown at a time, there isn't any real reason to want to bind two Activities at a time.
But, if you'd like, the best solution is to bind the Service in the onResume() method, and unbind it in the onPause() method. This allows you to give two unrelated Activities access to the service, while only having one bound at a time.
Each Activity is responsible for binding and unbinding from the Service. This is normally done in onResume / onPause, or onStart / onStop, depending on your requirements. One Activity cannot bind another Activity to a Service. That's just the way it is. :)
You can do it by using Messenger that provide IPC communication without using AIDL. This is how you can bind multiple activities to a service.
If you need your service to communicate with remote processes, then
you can use a Messenger to provide the interface for your service.
This technique allows you to perform inter-process communication (IPC)
without the need to use AIDL.
Have a look at this link. When you see the code, you will find a switch case within a Handler. This will cater to the multiple requests that you will send from you multiple activities/components.
I have a service that listens to a socket. When receiving certain input it is to create an activity. When receiving other input, it is to kill this activity. I have struggled for a while to make the service communicate with the activity through AIDL (http://developer.android.com/guide/developing/tools/aidl.html), but this seems to not be effective. I think AIDL is only effective when the process that is to be talked to is a service, not when it is an activity? I would love some directions or suggestions on how to solve my problem.
Cheers,
I have a service that listens to a
socket. When receiving certain input
it is to create an activity.
Please make this configurable. Services should not be starting activities except in very unusual circumstances (e.g., the socket is a SIP connection and you are creating a VOIP client). Popping up an activity interrupts the user in whatever they are doing.
When receiving other input, it is to
kill this activity.
The only scenario I have seen where this is a valid pattern is dismissing the in-call screen when the other party hangs up the line. If you are creating a VOIP client, your proposed pattern should be OK, but otherwise, please reconsider having the activity vanish in the middle of the user using it.
I think AIDL is only effective when
the process that is to be talked to is
a service, not when it is an activity?
No, it works in the reverse direction too, but usually only if the activity is the one starting the service and binding to it. More importantly, AIDL is only for cross-process communication.
I would love some directions or
suggestions on how to solve my
problem.
You have not really provided enough information on the nature of the communication to give you a thorough answer. What, exactly, is the service trying to tell the activity? Is the activity also trying to communicate with the service?
The recommended pattern for ongoing communication from an activity to a service is to use the local binding pattern. You will find an example of this in your SDK samples, and you can find one here as well.
The service then has options for communicating back to the client: via a callback (e.g., the Handler in the answer supplied by Mr. Smiljanić) or via broadcast Intents. In the case of the callback, the activity would need to bind to the service in order to get access to an API to provide the callback object. The service would then hold onto that object and call methods on it during key events.
If your service is doing its primary work on a background thread, you will need to ensure that your UI operations get performed on the UI thread. The Handler is one approach to that.