ste9206 ste9206 - 6 days ago 5
Android Question

TCP Connection using Service

I have to implement an application. This application communicates with a server using TCP/IP.My application has to request the position to a server.Because the application must stay to listen server request, I think to use an IntentService. So I implement it:

public class Tasks extends IntentService{
public final int SERVERPORT = 8100;
private Socket socket;
PrintWriter out;
BufferedReader in;

public Tasks()
{
super("My task!");
}
protected void onHandleIntent(Intent intent)
{
try
{
InetAddress serverAddr = InetAddress.getByName("10.0.0.138");
socket = new Socket(serverAddr, SERVERPORT);
out = new PrintWriter(socket.getOutputStream());
//send the request to authenticate it
out.print("Hello man");
out.flush();

//now i need to receive the request Hello_ACK

in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String mServerMessage = in.readLine();

if(mServerMessage.equals("Hello_ACK"))
Log.d("show","connection completed");

//now how can I send KEEP_ALIVE message to server?
out.print("KEEP_ALIVE");
out.flush();
}
catch (IOException e)
{
e.printStackTrace();
} } }


I want to ask you some questions:
1. how IntentService maintain the TCP connection with the server?
2. every 5 minutes I have to send "KEEP_ALIVE" message to the server..how can I put it?
3.I've implemented this task for maintain the connection with the server; for calling position at the server, Have i to use a new thread (for examples a new class extends Runnable)?
4. is it wrong using an asynctask for doing the same work?
5. for communicate with the main UT, I have to implement a RegisterReceiver, it is wrong?
Thank you for your help.

Answer

After reading your clarification:

  • Using IntentService is fine by itself. Note that IntentService creates a worker thread to handle incoming intents.
  • Create your socket when your service is started or lazily the first time you receive an Intent. Don't reconnect/recreate the socket each time you receive a new intent as you currently do. Just re-use the existing socket. You might want to add support for re-connecting the socket when the connection drops, however (i.e. when you get an IOError). Creating the socket lazily might be preferable, because you will be doing it in the correct thread (i.e. the intent handler thread). See below.
  • You don't need a separate thread to wait for incoming data. Just do it in the intent handler thread that you already get for free. Incoming intents will be queued and your service will process them one after the other.
  • AsyncTask is a little confusing to many. Unlike postDelayed() AsyncTasks are real background operations with additional hooks for synchronized framing operations. Initially, AsyncTasks where executed asynchronously in a separate thread. DONUT introduced a thread pool and HONEYCOMB went back to a single thread to avoid common race conditions.

    Services are a little different. Creating a new service does not mean the service does run in its own thread. Rather, for the typical use case, the creating main Activity and a newly created Service share the same thread, waiting for incoming messages. Doing blocking (e.g. network IO) operations on the UI thread is a sure way to make your application unresponsive (and that's why Android prevents it by default).

  • For the keep-alives you could simply use Handler.postDelayed() in your service. (see Android run a Task Periodically). If you create the handler on your Intent handler thread (i.e. the one that IntentService creates for you) you should not even have to worry about concurrent access.
  • The simplest way to send out replies from your service back to any intent sender is to use Context.sendBroadcast(). To use it, register a BroadcastReceiver for your Activity with Context.registerReceiver(). The BroadcastReceiver will receive all Intents that match the filter. The usual method is to come up with a unique action name for the Intent and filter by that.

[Edit] Correct claims about AsyncTask handling.

Comments