2011-07-29 16 views
5

Buduję (no cóż, próbuję zbudować) prosty czytnik wiadomości Usenet. Poniższy kod działa. Przechwytuje nazwę użytkownika, host, hasło z SharedPreferences i łączy się z serwerem i pomyślnie je uwierzytelnia, jednak blokuje interfejs użytkownika, dopóki wszystkie zadania nie zostaną wykonane.Połącz z blokadą gniazd UI

Jak zmienić ten kod, aby nie blokował interfejsu użytkownika?

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); 

} 


} 

Odpowiedz

5

Wyjazd AsyncTask

+0

można przekazać mojego obiektu nntpClient do AsyncTask (a także nazwę użytkownika, hasło, smyczki gospodarza i wszystkiego innego?) – dotty

+0

utworzyć podklasę AsyncTask, i tak, można przekazywać argumenty do niego, lub utwórz konstruktor, który pobiera argumenty. – Kaj

+0

Czy możesz podać przykład przekazania tych zmiennych? – dotty

2

Jestem pewien, że niektóre z Androidem ekspertów skieruje Cię w kierunku różnych ram będziemy chcieli wykorzystać do realizacji tego, ale podstawowym problemem jest następujący.

Interfejs użytkownika jest pojedynczy wątek, który jest często nazywany wątkiem wywołania zdarzenia. Więc kiedy użytkownik kliknie przycisk i zrobisz coś, co zajmuje dużo czasu, to powstrzymuje interfejs użytkownika od robienia czegokolwiek innego w tym samym czasie.

Należy wykonać długie zadanie w innym wątku i upewnić się, że komunikacja między wątkiem EDT a wątkiem roboczym jest bezpieczna dla wątków.

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

Lepiej używać AsyncTask – Kaj

+0

@Kaj yes (: Thanks –