IPString У меня довольно простое действие, которое работает следующим образом: в onCreate я вызываю подключение AsyncTask TCP Socket к удаленному серверу через собственный порт, отправляю быструю команду ASCII на сервер и обрабатываю ответ через onPostExecute ().Прекрасно работает, это быстро и функционально.
Однако, если удаленный сервер не работает - или я ошибочно ввел неправильный IP-адрес для связи - мой AsyncTask будет зависать при вращении диалога «вход в систему»на экране столько времени, сколько требуется для истечения времени ожидания сокета.
Последние два дня я копался в этом, пытаясь выяснить, как вызывать метод cancel (), но мне это не удается.Какие-либо предложения?Вот текущий код:
public class Scratchpad extends AsyncTask<Object, String, String>{
private String returningResponse;
private volatile Socket socket;
@Override
protected void onPreExecute(){
//throw the "Logging In" dialog up
initializeDialog();
super.onPreExecute();
}
@Override
protected void onProgressUpdate(String... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String result) {
//send the ASCII result off to the function that parses through it
loginTriggerResult(result);
super.onPostExecute(result);
}
@Override
protected String doInBackground(Object... params) {
/*
* bunch of stuff goes here to strip out the proper
* values from the Object for IP address, Port number etc.
* params[0], params[1] etc.
*
*/
InetAddress serverIP = null;
String IPString = (String) params[1];
int portnumber = (Integer) params[2];
//convert the String "IPString" into an InetAddress
try {
serverIP = InetAddress.getByName(IPString);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
//and then, bingo bango bongo, make the connection with the 'try':
try{
socket = new Socket(serverIP.getHostAddress(), portnumber);
//I tried this too, forcing the timeout... It crashes immediately.
//SocketAddress socketAddress = new InetSocketAddress(serverIP.getHostAddress(), portnumber);
//socket.connect(socketAddress, 3000);
Log.d("networking","Connection Completed");
//bunch of stuff goes here that happens AFTER the solid connection,
//which we never get to if the Socket fails on a "waiting to connect" thing.
//reader.close();
//outputStream.close();
}catch (SocketException e){
e.printStackTrace();
Log.w("socket","socket closed with SocketException");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.w("socket","socket closed with IOException");
}
return returningResponse; //postExecute will handle this.
}
}
Я не получаю ни одного из сообщений журнала, пока не истечет 3 или 4 минуты, что время ожидания сокета истекло.Я думаю, что должен быть способ запустить TimerTask или что-то вне AsyncTask, чтобы отследить, сколько времени требуется, чтобы установить соединение (или нет), а затем каким-то образом «отменить ()» выполнение «try» внутри AsyncTask,но я терпел неудачу во многих стилях.
Это должно быть чем-то, что обычно используется, и должно быть простое решение?
ОБНОВЛЕНИЕ: Путь Iнаправлялся вниз, пытался использовать сокетное соединение из AsyncTask, чтобы «контролировать себя», и если / когда оно истекло, без получения надежного соединения - вызвать cancel () AsyncTask.Я пытался сделать это из самого AsyncTask, с помощью this.cancel () внутри перехвата IOException тайм-аута Socket.
До сих пор решение заключается в реализации таймера вне AsyncTask, который запускается нато же самое время, что и AsyncTask, и вызвать отмена после того, как прошло много секунд.Это решение изящно завершает попытку подключения, и я могу поместить любые триггеры Dialog или тосты в раздел onCancelled () AsyncTask.Он больше не падает, НО: сокет все еще пытается подключиться в фоновом режиме, даже если задача отменяется.