必须从UI线程调用AsyncTask-Method getText

时间:2016-04-11 21:55:55

标签: java android multithreading android-studio

下的“必须从UI线程调用方法getText”错误
edtUrl.getText().toString();

我认为我必须在AsyncTask中添加一个构造函数,这将使两个字符串在创建任务时发送它们吗?有人有主意吗?尝试使用另一个SO问题就像这个信息但没有任何效果

 private class ParseURL extends AsyncTask<String, Void, String> {
      private String siteUrl;
    @Override
    protected String doInBackground(String... strings) {
        StringBuffer buffer = new StringBuffer();
        //EditText edtUrl = (EditText) findViewById(R.id.edtURL);

        //String siteUrl = edtUrl.getText().toString();
        try {
            Log.d("JSwa", "Connecting to ["+strings[0]+"]");
            Document doc  = Jsoup.connect(strings[0]).get();
            Log.d("JSwa", "Connected to ["+strings[0]+"]");
            // Get document (HTML page) title
            String title = doc.title();
            Log.d("JSwA", "Title ["+title+"]");
            buffer.append("Title: " + title + "\r\n");


            try {
                doc = Jsoup.connect(siteUrl)
                        .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
                        .referrer("http://www.google.com")
                        .timeout(1000 * 5) //it's in milliseconds, so this means 5 seconds.
                        .get();
            } catch (Throwable t) {
                t.printStackTrace();
            }

            Elements tableElements = doc.select("td");
            for (Element td : tableElements) {
                buffer.append("TT [" + td + "] \r\n");
                Log.d("JSwA", "TT [" + td + "]");
            }

这是我的onClick(),我在下面的siteURl下得到错误。

       @Override
        public void onClick(View view) {
           // String siteUrl = edtUrl.getText().toString();
            siteUrl = "http://www.w3schools.com/html/html_tables.asp";
            (new ParseURL()).execute(new String[]{siteUrl});

这是我尝试使用的findViewsById()方法。

          protected void onPreExecute() {
        super.onPreExecute();
        EditText edtUrl = (EditText) findViewById(R.id.edtURL);
         siteUrl = edtUrl.getText().toString();
    }

尝试将此代码合并到我的项目中时出现错误,它是我的parseURL方法的一部分:

 try {
        doc = Jsoup.connect(siteUrl)
                .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
                .referrer("http://www.google.com")
                .timeout(1000 * 5) //it's in milliseconds, so this means 5 seconds.
                .get();
    } catch (Throwable t) {
        t.printStackTrace();
    }

2 个答案:

答案 0 :(得分:3)

只有UI线程可以使用UI组件。 doInbackground()在不同的线程上运行,该线程无法访问UI组件。

您可以将字符串设置为模块化,并使用onPreExecute()方法获取文本,然后在doInBackground()方法中使用它:

private class ParseURL extends AsyncTask<String, Void, String> {
    private String siteUrl;

    .
    .
    .


    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        EditText edtUrl = (EditText) findViewById(R.id.edtURL);
        siteUrl = edtUrl.getText().toString();
    }


@Override
protected String doInBackground(String... strings) {
    try {
        doc = Jsoup.connect(siteUrl)
            .userAgent("Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:25.0) Gecko/20100101 Firefox/25.0")
            .referrer("http://www.google.com")
            .timeout(1000 * 5) //it's in milliseconds, so this means 5 seconds.
            .get();
    } catch (Throwable t) {
        t.printStackTrace();
    }

    .
    .
    .

}

希望它有所帮助。

答案 1 :(得分:0)

看起来您正在尝试获取用户输入的网址,然后与服务器联系以执行某些操作。这样做的方法是在创建任务时发送url,然后将其作为任务中doInBackground()方法的参数检索。

因此,您将使用以下声明传递网站网址:(new ParseURL()).execute(siteUrl);

然后你会在doInBackground()方法中检索它,如下所示:

@Override
protected String doInBackground(String... strings) {
    String siteUrl = strings[0];
}

(String... strings)允许您发送任意数量的String参数,并且将使用您传入的任何参数创建动态数组。因此,由于我们只传入一个String(我们的站点URL),使用我们的url作为唯一参数创建大小为1的字符串数组。所以现在你只需像上面那样访问它。

你获得&#34; UI线程的原因&#34;错误是因为您无法操纵UI线程中的UI元素。由于AsyncTask在后台运行UI线程,因此会收到错误。解决方案是在UI线程上获取所需的数据,然后在创建时将其传递给Task。

希望这能为你澄清事情!