2015-09-09 6 views
9

ich eine AsyncTask in meiner Anwendung haben:Kraft eine Sperr stoppen lesen 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; 
     } 
     ... 
    } 

Und ich will task AsyncTask stoppen, wenn ich meine Anwendung zu schließen: (Presse zurück putton). Ich habe versucht, die Antwort hier Android - Cancel AsyncTask ForcefullyisCancelled()

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

zu überprüfen, aber es scheint, dass die Anwendung wird bei myInputstream.read(readbyte) blockieren, wenn task.cancle(true) genannt wird. Android wird ein "App reagiert nicht mehr ..." Pop-up zu mir werfen. Wie kann ich das Blockieren des Lesevorgangs erzwingen?

+0

Fangen Sie irgendwelche Ausnahmen in doInBackground? Es sollte eine InterruptedException geben. – Fildor

+0

@Fildor sollte es eine "java.io.InterruptedIOException" sein, aber nur, wenn der Stream eine Unterbrechung unterstützt. – SpaceTrucker

+0

Sie sagen: "Es scheint, dass die Anwendung bei' myInputstream.read (readbyte) '" blockiert. Wie sicher bist du, dass das tatsächlich der Fall ist? – SpaceTrucker

Antwort

0

java.io.InputStream implementiert blockierende E/A. Es wird erwartet, dass die Anwendung auf

myInputstream.read(readbyte) 

blockiert, bis der read Betrieb -1 zurückkehren wird, was bedeutet, dass es keine weiteren Daten aus dem Stream zu lesen (wie es geschlossen wurde oder die Verbindung wurde abgebrochen) oder die Ausnahme werfen.

Die einzige Möglichkeit, den Thread, der auf Daten im Stream wartet, zu entsperren, besteht darin, ihn zu schließen. In Ihrem Fall müssen Sie die Socket erstellt zu nahe an der Lage sein, in

mySocket = new Socket(); 

Linie.

mySocket.close(); 

sollte Ihre Lesung unterbrechen. Aber beachten Sie, dass Socket.close() tatsächlich

Schließt diesen Sockel.

Alle Threads, die derzeit bei einer E/A-Operation für diesen Socket blockiert werden, lösen eine SocketException aus.

So Sie Aufgabe Profil unblockierten bekommen, aber Sie haben die SocketException richtig in Ihrer Aufgabe zu behandeln alle Operationen zu beenden (vielleicht ist es das, was Sie fehlen).

FYI die

task.cancel(true); 

ruft nicht nur machen viel Sinn, da dies die cancelled Flagge Aufgabe setzt. Es ist Aufgabe Ihres Codes, nach der Flagge zu suchen, und mit der Blockierung von E/A haben Sie keine Möglichkeit, dies zu tun.

Alternativ sollten Sie nicht blockierende E/A in Betracht ziehen.