如何从后台线程

时间:2017-02-01 15:41:54

标签: android android-asynctask jsoup

我想更改textView的文本以匹配网站的标题。

为此,我正在连接https://www.google.com并获取其html源代码。然后我从中获取标题标签。 (使用JSoup)

问题是现在我不知道如何更改textView。由于网络是在后台线程中发生的,我无法访问它。我该怎么做,在哪里做?

此外,由于Log.w,我知道它已成功连接。

这就是我所拥有的:

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

3 个答案:

答案 0 :(得分:1)

TextView内初始化onCreate()Button相同。使用班级textView

Asynctask传递给Constructor

完整解决代码:

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 Class:

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

答案 1 :(得分:0)

此问题向您展示如何解决您的问题:how do i send data back from onPostExecute in an AsyncTask?

更改调用活动的doStuff()接口方法中的TextView。

答案 2 :(得分:0)

我假设你想要知道,如何从doInBackground()方法或后台线程访问或更改UI组件,提供AsyncTask或。为此,您需要使用处理程序。例如,在AsyncTask类中初始化Handler的对象 现在在doInBackground()方法中调用方法handler.post()或在下面的线程的Run()方法中调用

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

记得在doInBackground()或run()方法之外初始化处理程序;