views:

589

answers:

1

Hi,

I have created a multithreaded application but it still hangs if the server is unavailable.

In the main Activity I've created the following methods:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    //bind GUI elements
    ...

    //start TCPConnection Service in a new thread
    establishTCPConnection();
    ...

}


private void establishTCPConnection(){
    TCPClientServiceThread = new Thread(null, backgroundConnection, "connection");
    TCPClientServiceThread.start();
}

..


private Runnable backgroundConnection = new Runnable(){
    public void run(){
     //establish TCP connection
     doEstablishTCPConnection();
    }
};

private void doEstablishTCPConnection()
{
    //start TCPConnection service
    startService(new Intent(this, TCPClientService.class));
}

And this is the TCPClientService Class:

public class TCPClientService extends Service{

...

private String serverAddress = "192.168.1.5";
private int portNumber = 1000;



@Override
public void onCreate()
{
 //TODO: Actions to perform when service is created
 connectionAvailable = false;

 IntentFilter dataReceiverFilter;
 dataReceiverFilter = new IntentFilter(MotranetClient.MOTION_DATA_UPDATED);
 dataReceiver = new DataReceiver();
 registerReceiver(dataReceiver, dataReceiverFilter);

 EstablishConnection();
}

@Override
public IBinder onBind(Intent intent)
{
 //TODO: Replace with service binding implementation
 return null;
}

private void EstablishConnection()
{
 try {
           InetAddress serverAddr = InetAddress.getByName(serverAddress);
           Log.d("TCP", "C: Connecting...");
           Socket socket = new Socket(serverAddr, portNumber);
           String message = "testing connection";

               try {
                Log.d("TCP", "C: Sending: '" + message + "'");
                PrintWriter out = new PrintWriter( new BufferedWriter( new OutputStreamWriter(socket.getOutputStream())),true);
                out.println(message);
                Log.d("TCP", "C: Sent.");
                  Log.d("TCP", "C: Done.");
                  connectionAvailable = true;

             } catch(Exception e) {
                 Log.e("TCP", "S: Error", e);
                 connectionAvailable = false;

               } finally {
                  socket.close();
                  announceNetworkAvailability(connectionAvailable);
                }

         } catch (Exception e) {
              Log.e("TCP", "C: Error", e);
              announceNetworkAvailability(connectionAvailable);
         }
    }


}

When the server is unavailable the line

Socket socket = new Socket(serverAddr, portNumber);

causes some delay and I believe this is the cause for hanging. But if the TCPClientService Service is executing in its own thread I don't know why this affects the timeout of the main activity.

I would be very thankful if anyone could show how to prevent the application from hanging when the server is unavailable.

Thanks!

Niko

+1  A: 

The Android platform -always- runs lifecycle methods for Activitys and Services in the main event thread. So you create another thread, and call startService from it... but when the Service is created and started the onCreate() etc methods are being called from the main event thread, -not- from your user thread.

The proper way to do this is not to call startService from another thread, but to call startService normally, and then have the Service spawn a connection thread from within onCreate().

ssakl's solution does not address the basic problem I'm afraid.

Soonil
It works! Thanks for help!
niko