2017-02-01 4 views
0

Ich möchte den Text eines textView ändern, um dem Titel einer Web site zu entsprechen.Wie man TextView Eigenschaften vom Hintergrundthread ändert

Dafür verbinde ich mich mit https://www.google.com und bekomme seinen HTML-Quellcode. Dann hole ich das Title-Tag von ihm. (mit JSoup)

Das Problem ist, dass ich jetzt nicht weiß, wie Sie die TextView ändern. Da die Vernetzung in einem Hintergrundthread stattfindet, habe ich keinen Zugriff darauf. Wie und wo soll ich es machen?

Auch ich weiß, dass es dank Log.w. erfolgreich verbunden ist.

Hier ist, was ich habe:

MainActivity

public class MainActivity extends AppCompatActivity { 

    Button btnConnect; 

    final String URL = "https://www.google.com"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     btnConnect = (Button) findViewById(R.id.btnConnect); 
     btnConnect.setOnClickListener(new View.OnClickListener() { 
      public void onClick(View v) { 
       // launch networking task 
       new EstablishConnectionTask().execute(URL); 
      } 
     }); 


    } 
} 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/activity_main" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:paddingBottom="@dimen/activity_vertical_margin" 
    android:paddingLeft="@dimen/activity_horizontal_margin" 
    android:paddingRight="@dimen/activity_horizontal_margin" 
    android:paddingTop="@dimen/activity_vertical_margin" 
    tools:context="com.awakened.tirafesi.awakenedprototype.MainActivity"> 

    <Button 
     android:text="Establish Connection" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_centerVertical="true" 
     android:layout_centerHorizontal="true" 
     android:id="@+id/btnConnect" /> 

    <TextView 
     android:text="Placeholder" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_alignParentTop="true" 
     android:layout_centerHorizontal="true" 
     android:layout_marginTop="87dp" 
     android:id="@+id/txtTitle" /> 
</RelativeLayout> 

EstablishConnectionTask

public class EstablishConnectionTask extends AsyncTask<String, Void, String> { 


    @Override 
    protected String doInBackground(String... urls) { 

     String title; 

     try { 
      Document doc = Jsoup.connect(urls[0]).get(); 
      title = doc.title(); 

     } catch (IOException e) { 
      e.printStackTrace(); 
      title = "NO"; 
     } 

     return title; 
    } 

    @Override 
    protected void onPostExecute(String s) { 
     super.onPostExecute(s); 

     Log.w("Title", s); 
    } 
} 
+0

Schreiben Sie einen Listener und senden Sie es an Ihre ** EstablishConnectionTask ** dann in OnPostExecute rufen Sie einfach Ihre Schnittstelle Methode. In Ihrer MainActivity implementieren Sie zuerst diesen Listener und in seiner Override-Methode können Sie den textView-Titel festlegen. – eminuluyol

+1

Um auf das, was @eminululyol gesagt hat, aufzubauen, gibt diese Frage ein Codebeispiel: http://stackoverflow.com/questions/9447646/how-doi-isend-data-back-from-onpostexecute-in-a-asynctask – RScottCarson

+0

Ich verstehe es nicht ... Wie würde die Außerkraftsetzung der Interface-Methode auf MainActivity den Aufruf der Schnittstelle in onPostExecute beeinflussen? Würde es Ihnen etwas ausmachen, den Code dafür hinzuzufügen? – Tirafesi

Antwort

1

Initialisiere TextView innerhalb onCreate() wie für Button. Übergeben Sie die textView, zu Asynctask mit der Klasse Constructor:

komplette Gelöst Code:

public class MainActivity extends AppCompatActivity { 

Button btnConnect; 
TextView textView; 

final String URL = "https://www.google.com"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    textView = (TextView) findViewById(R.id.txtTitle); 
    btnConnect = (Button) findViewById(R.id.btnConnect); 
    btnConnect.setOnClickListener(new View.OnClickListener() { 
     public void onClick(View v) { 

      //pass TextView of this class to Asynctask cass 
      new EstablishConnectionTask(textView).execute(URL); 
     } 
    }); 
    } 
} 

AsyncTask Klasse:

public class EstablishConnectionTask extends AsyncTask<String, Void, String> { 

public TextView textView; 

//constructor to pass textView 
public EstablishConnectionTask(TextView textView){ 
    this.textView = textView; 
} 

@Override 
protected String doInBackground(String... urls) { 

    String title; 
    try { 
     Document doc = Jsoup.connect(urls[0]).get(); 
     title = doc.title(); 

    } catch (IOException e) { 
     e.printStackTrace(); 
     title = "NO"; 
    } 
    return title; 
} 

@Override 
protected void onPostExecute(String s) { 
    super.onPostExecute(s); 
    textView.setText(s); // add title to textView 

    Log.w("Title", s); 
} 
} 
0

Ich gehe davon aus Sie wissen wollen, wie die Benutzeroberfläche zugreifen oder ändern Komponenten aus der doInBackground() - Methode oder einem Hintergrundthread, bereitgestellt von AsyncTask oder. Um dies zu erreichen, verwenden Sie einen Handler. Zum Beispiel in der Klasse AsyncTask ein Objekt von Handler jetzt Aufrufmethode handler.post() in doInBackground() Methode oder in Run() Methode des Thread initialisieren wie unten

Handler handler = new Handler(); 
handler.post(new Runnable{ 
@overide 
public void run(){ 
    textView.setText("Changed"); 
} 
}); 

daran denken, die außerhalb des Handlers doInBackground zu initialisieren() oder run() -Methode;

Verwandte Themen