2015-09-09 10 views
9

Ho un AsyncTask nella mia domanda:Forza fermare un blocco lettura AsyncTask

public class myActivity extends Activity { 
    private static Socket mySocket; 
    private static InputStream myInputstream; 
    private AsyncTask task; 
    private boolean connected = false; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     ...    
     task = new UpdateTask().execute(); 
     ... 
    } 

    private class myTask extends AsyncTask<Void, String, String> { 
     @Override 
     protected String doInBackground(Void... v) { 
      if(!connected) { 
       try { 
        mySocket = new Socket(); 
        mySocket.connect(new InetSocketAddress(MYIP, MYPORT)); 
        myInputstream = mySocket.getInputStream(); 
        connected = true; 
       } catch(IOException e) { ... } 
      } 

      while(connected && !isCancelled()) { 
       byte[] readbyte = new byte[1024]; 
       try { 
        myInputstream.read(readbyte); 
       } catch (IOException e) { ... } 
       ... 
      } 
      return null; 
     } 
     ... 
    } 

E voglio smettere AsyncTask task quando chiudo la mia domanda: (premere indietro putton). Ho provato la risposta qui Android - Cancel AsyncTask Forcefully per controllare isCancelled()

@Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if(keyCode == KeyEvent.KEYCODE_BACK) { 
      task.cancel(true); 
      mySocket.close(); 
      finish(); 
     } 
     return super.onKeyDown(keyCode, event); 
    } 

ma sembra che l'applicazione si blocca in myInputstream.read(readbyte) quando task.cancle(true) si chiama. Android salterà una "app smette di rispondere .." popup a me. Come posso forzare l'interruzione della lettura del blocco?

+0

Rilevate eccezioni in doInBackground? Ci dovrebbe essere un InterruptedException. – Fildor

+0

@Fildor dovrebbe essere un 'java.io.InterruptedIOException', ma solo se il flusso supporta l'interruzione. – SpaceTrucker

+0

Si dice "sembra che l'applicazione si blocchi a' myInputstream.read (readbyte) '". Come sei sicuro che questo sia effettivamente il caso? – SpaceTrucker

risposta

0

java.io.InputStream implementa il blocco dell'I/O. Si prevede che l'applicazione si blocca su

myInputstream.read(readbyte) 

finché l'operazione read tornerà -1 che significa che ci sono più dati da leggere dal flusso (perché era chiuso o connessione è stata interrotta) o generare l'eccezione.

L'unico modo per sbloccare il thread in attesa di dati sul flusso è chiuderlo. Nel tuo caso è necessario essere in grado di chiudere la Socket creata in

mySocket = new Socket(); 

linea.

mySocket.close(); 

dovrebbe interrompere la lettura. Ma state attenti che Socket.close() effettivamente

Chiude questa presa.

Qualsiasi thread attualmente bloccato in un'operazione di I/O su questo socket genera una SocketException.

Così si battistrada compito sarà ottenere sbloccato ma si deve gestire la SocketException correttamente nel vostro compito di interrompere tutte le operazioni (forse questo è ciò che si sta perdendo).

FYI chiamando il

task.cancel(true); 

non ha molto senso in quanto questo imposta solo la bandiera cancelled sul compito. È responsabilità del tuo codice controllare la flag e con I/O di blocco non hai la possibilità di farlo.

In alternativa, è possibile utilizzare l'I/O non bloccante.