I am working on a project that. It will connect to a remote host using tcp sockets from a service. And interact with it for getting and sending data.
The flow, I have planned is;
a singleton socket class. Which returns a connected socket refference;
an activity to ask user for remote server's ip and port.
a service triggered(intent) by the activity with the parameters of ip:port.
service will get the socket using singleton socket class.
and then service will read a data; parse it and show user for user actions in a new action window ( intended).
after user completed the action; result will be sent to the server. and new request will be read.
problem/query is here;
when you come back to the service for second data read operation; will the socket be there ? (or garbage collected )
because after data read operation started no new connection accepted.
will the first service die after calling the user actions activity ?
what happens if I call the service using startService from an activity, a new service created or the existing before started service called back again ?
how can I let the service live for ever unless I said it to die.
Sorry, If I am asking silly questions.
Here's how I see it:
when you come back to the service for second data read operation; will
the socket be there ? (or garbage collected ) because after data read
operation started no new connection accepted.
If the object is static and has the socket as a member variable it will most likely be there, you should have safeguards in your single pattern to shield from this problem (if single==null){...}, you could also try managing it by overriding the Application class and adding a factory method in there. You need to make sure the socket is open and closed correctly and not just left hanging as this could create problems
EDIT:
Whether the actual socket is still open will depend on the timeout of the socket
will the first service die after calling the user actions activity ?
Services need to be told to stop and so it will not die
what happens if I call the service using startService from an
activity, a new service created or the existing before started service
called back again ?
If the service is running, the it will not create another, it will call the onStartCommand() of the running service
how can I let the service live for ever unless I said it to die.
This is default behavior
Related
Consider there is 1 service and 2 Activity.
Activity 1 is for connecting to the bluetooth device.
Activity 2 is for getting the data from the BLE Device
I have implemented both the connection and data read part Using Service because there is a need to collect data from BLE device even when the app is in background mode.
So how can I use the service to make connection during the Activity 1 and use the same service from Activity 2 for collecting the data with the same connection.
You need to make sure that your Service runs until you explicitly shut it down. Return START_STICKY from onStartCommand() and your Service will stay running even if the client Activity unbinds. Make sure that you have some way to shut the Service down (using stopService() or stopSelf() when you are done with it.
I haven't worked on a bluetooth service.But I guess you can create a bluetooth stream object in the first activity which can be shared with the second activity.Use the stream object in the second activity to do communications.
This is the link to my code. On service start a socket a created that sends data to the server from android client. This service is stopped on destroy.
But I noticed, if my client loses connection with the server I have no way of knowing it and worse I cannot reconnect to the server.
I assume the best way would be to receive an echo of the command sent by the client to the server and if there is no reply from server understand that the connection is lost. After knowing that the connection is lost I need to self stop the service and restart it. I have no idea how to go about it. After doing this I need to rebind to the activity.
The other way is the client socket should be opened and closed for every data being sent. This way it automatically reconnects to the server. I do not know how to do this too.
Any help is appreciated
I have modified my code to implement the second solution suggested in the question. Instead of creating a socket on startservice(), I now create it and close it everytime the client wants to send data. This way I do not have to stop my service on connection loss. The Server side I modified to be indefinitely listening to the port unless indicated by the client to break out of the loop and disconnect.
public void sendMessage(String message){
//making message variable global to the SocketSevice class
this.message=message;
//connecting to class that performs socket connection
Runnable connect = new connectSocket();
new Thread(connect).start();
}
When you want to restart your service just send a broadcast message to one of your activity.
on receiving your broadcast message write a piece of code to start the service on the activity which your broadcast receiver is defined. (kill the service inside of service class or on the broadcast receiver class)
I'm developing an application on android 3.1 and I have an Activity A that has a subclass extending from aSyncTask, this subclass create a socket and connect to a server. All my communication is good. I received messages and send commands to a server, but when I got a specific command I have to start a second activity (activity B) but I can't lost my socket and the establish communication with the server, plus I have to still able to receive and send commands from activity B to server. How can I do that??
Any help please!
My approach is implementing a service and move/centralise all your network connection code into service, for all activities that want to use socket connection, bind your network service in onCreate() then after finish unbind it in onDestory()
According to Dianne Hackborn (Android engineer), the recommended practice to pass network connections between activities is to create a singleton that any activity can access and manage the connection from there. See here and check the first post by Dianne.
The Services page on the android developers site (side note under the 'Basics' Section) also mentions that you should only use a service if you need to run code that needs to continue execution while your application is in the background.
I have a local service that will need to wait for a response and when it gets the response immediately update the activity with that information. So the activity will not poll a service method but the moment the local service gets some data it has to inform that activity immediately somehow.
So Activity--binds-->LocalService <------>(RemoteService separate process). So I know I could just package it up in an intent and pass it up to the activity ... but is that the best/only option. How else might one communicate up the stack from the local service to the activity thats invoking the local service? Keep in mind I already have the local service binding to a remote separate process service which runs forever in the background and periodically sends realtime data to the local service. Thanks
you can pass the handler object of the activity to service thru setter() and using this object you can update the change in the activity.
I'm an android noob that is looking for some advice on how to properly use a service in Android. I am building an app that will connect to a server on the Internet to get a data stream via TCP. That data then needs to get send out to another device that is connected via a bluetooth serial port. I want this to continue to function in the background while the user looks at a different activity.
The app will be a NTRIP client, which pulls real time RTK correction data from the Internet and sends it to a RTK GPS receiver that I connect to via bluetooth. The data rate will be about 500 bytes/second. The user interface is a single button to connect or disconnect the data stream and some text to show status of the GPS receiver. There are also a few settings that will need to be configured by the user such as the IP/port of the server to connect to and the bluetooth device to communicate with.
I think I need to have the main activity spawn a local service, and then have the service spawn a thread for the TCP stream and another thread for the bluetooth connection. Does this sound right?
What is the best model for the service in this scenario?
-Start(bind) the service every time the activity starts, and have the connect/disconnect button send commands to the service to start/stop the threads. If I go this route, the service will continue to run after the user disconnects and goes to another app. The service would need an inactivity timer to terminate itself.
-Start and stop the service when the user presses the connect/disconnect button. The service only runs when data is moving. If I do this, the activity will need to see if the service is running when the activity starts, in order to know if it should bind to the service or tell the user that the link is disconnected.
Thanks.
I'd go with your second option. Checking if a service is running or not is an easy task and also you won't consume unnecessary processing time which will be better for the battery life.
Just because you can run a service for a long time in the background doesn't necessarily mean that you also should do that. At least not all the time.
As android supports more than one entry point into the app, you could define two entry points in the Manifest.xml.
<category android:name="android.intent.category.LAUNCHER" /> defines, that this class could be started from the launcher. I guess that would work for a service, too. I would do two entry points. One which spawns the activity first and gives the user some configuration control. And another which simply spawns the service.
As you have no control over the lifetime of an activity i would not suggest to do anything which should not be ended by the system. If you have an incoming call your activity would simply die.
If the user starts the service you could create an widget with the button. If the user starts the activity you could start the service and the widget.
And if the user starts the widget, the user decides, what should happen with the service.
I'm not a Java or Android programmer so take what I say with a grain of salt. The normal way to handle blocking IO in Java is to use threads. It sounds like the data flow is unidirectional but for maximum flexibility I would create 3 threads, one for the UI, one for the TCP connection and one for the bluetooth connection. Communication between the UI and two worker threads could be done using shared variables (need to careful about synchronization, race conditions, etc). I would pass the data NTRIP data to the other worker using a multi-threaded queue data structure.
The worker thread for the NTRIP data would be roughly:
while (app running) {
if (connection enabled) {
if (not connected) {
c = connect to remote
}
data = get data from c
queue.put(data)
if (options reconfigured) {
close c
}
}
}
For the bluetooth thread:
while (app runnning) {
data = queue.get()
if (UI settings changed and connected) {
close connection
}
if (not connected) {
c = connect to remote
}
send data over connection
}
In the normal state, both workers are blocking on IO and will be consuming essentially no CPU time. Based on my experience, I would recommend you write your code to handle communication errors. For your code to work well in the real world you have to handle connections closing, hanging, etc. Making it robust will likely be the most time consuming part of the development.