2011-07-29 12 views
5

Estoy compilando (bueno, intentando compilar) un lector de noticias de usenet simple. El código a continuación funciona. Captura el nombre de usuario, el host y la contraseña de SharedPreferences, se conecta al servidor y se autentica con éxito, sin embargo, bloquea la interfaz de usuario hasta que se completan todas las tareas.Conectar a un socket bloquea la interfaz de usuario

¿Cómo cambiaría este código para que no bloquee la IU?

package com.webfoo.newz; 

import java.io.IOException; 
import java.net.SocketException; 

import android.app.Activity; 
import android.content.Intent; 
import android.content.SharedPreferences; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.TextView; 
import org.apache.commons.net.nntp.NNTPClient; 

public class NewzActivity extends Activity { 

TextView statusText; 
String PREFS_NAME = "MyPrefsFile"; 
SharedPreferences settings; 
NNTPClient nntpClient; 
int port; 
String username; 
String password; 
String host; 


/** Called when the activity is first created. */ 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 
    this.statusText = (TextView)findViewById(R.id.connectionStatusTextView); 
    this.nntpClient = new NNTPClient(); 
    this.settings = getSharedPreferences(PREFS_NAME, 0); 
} 

public void openSettings(View button){ 
    Intent settingsIntent = new Intent(NewzActivity.this, SettingsActivity.class); 
    startActivity(settingsIntent); 
} 

public void makeConnection(View button) { 

    this.statusText.setText("Connecting...");  
    this.port = settings.getInt("UsenetPort", 563); 
    this.host = settings.getString("UsenetHost", ""); 
    this.nntpClient.setDefaultPort(port); 
    this.nntpClient.setDefaultTimeout(9999); 
    // this.nntpClient.setConnectTimeout(9999); 
    this.statusText.setText("Connecting to " + host); 

    try { 
     this.nntpClient.connect(host); 
    } catch (SocketException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    this.statusText.setText("Connected to " + host); 

    if(nntpClient.isConnected()){ 
     setAuthDetails(); 
    }else{ 
     this.statusText.setText("Failed to Connected to " + host); 
    } 

} 

private void setAuthDetails() { 

    this.username = settings.getString("UsenetUsername", ""); 
    this.password = settings.getString("UsenetPassword", ""); 

    try { 
     nntpClient.authinfoUser(username); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 
    try { 
     nntpClient.authinfoPass(password); 
    } catch (IOException e) { 
     // TODO Auto-generated catch block 
     e.printStackTrace(); 
    } 

    statusText.setText("Authenticated as " + username); 

} 


} 

Respuesta

5

Salida AsyncTask

+0

¿Puedo pasar mi objetivo nntpClient a un AsyncTask (así como el nombre de usuario, contraseña, Cuerdas anfitrionas y todo lo demás?) – dotty

+0

Se crea una subclase de AsyncTask, y sí, puede pasar argumentos a ella, o crea un constructor que tome argumentos – Kaj

+0

¿Puedes dar un ejemplo de cómo pasar esas variables, por favor? – dotty

2

Estoy seguro de que algunos de los expertos Android le apuntan en la dirección de los diversos marcos que querrá utilizar para implementar esto, pero el problema básico es el siguiente.

La interfaz de usuario tiene un solo subproceso, ese subproceso se denomina a menudo subproceso de envío de evento. Por lo tanto, cuando un usuario hace clic en un botón y hace algo que lleva mucho tiempo, eso impide que la IU haga cualquier otra cosa al mismo tiempo.

Lo que necesita hacer es realizar cualquier tarea larga en un hilo diferente y asegurar que la comunicación entre el subproceso EDT y su subproceso de trabajo sea segura para subprocesos.

0
Thread T = new Thread(new Runnable(){ 
    public void run(){ 
     /////////////////////////////// 
     //YOUR CODE 
     /////////////////////////////// 
    } 
}); 


     //IF YOU WANT TO MANIPULATE THE UI inside the run() 
     //USE: 
runOnUiThread(new Runnable() { 
@Override 
public void run() { 
    /////////////////////////////// 
    //Your Code 
    /////////////////////////////// 
    } 
}); 
+0

Es mejor usar la AsyncTask – Kaj

+0

@Kaj sí (: Gracias –

Cuestiones relacionadas