¿Cómo evitar el tiempo de espera de la aplicación?
-
19-08-2019 - |
Pregunta
He creado una aplicación multiproceso pero todavía se cuelga si el servidor no está disponible.
En la Actividad principal, he creado los siguientes métodos:
@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));
}
Y esta es la clase TCPClientService:
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);
}
}
}
Cuando el servidor no está disponible, la línea
Socket socket = new Socket(serverAddr, portNumber);
causa algún retraso y creo que esta es la causa de colgar. Pero si el servicio TCPClientService se está ejecutando en su propio hilo, no sé por qué esto afecta el tiempo de espera de la actividad principal.
Estaría muy agradecido si alguien pudiera mostrar cómo evitar que la aplicación se cuelgue cuando el servidor no está disponible.
Solución
La plataforma Android -siempre- ejecuta métodos de ciclo de vida para Actividades y Servicios en el hilo principal del evento. Entonces crea otro hilo y llama a startService desde él ... pero cuando el Servicio se crea e inicia, los métodos onCreate (), etc. se invocan desde el hilo principal del evento, no desde su hilo de usuario.
La forma correcta de hacer esto no es llamar a startService desde otro hilo, sino llamar a startService normalmente y luego hacer que el Servicio genere un hilo de conexión desde onCreate ().
La solución de ssakl no aborda el problema básico, me temo.