异步任务中的运行时错误

时间:2014-10-21 16:15:17

标签: java android

我正在尝试使用Asycn Task构建一个简单的程序,点击“获取”按钮会在webview中加载google主页。我没有在代码中显示错误,但是当我单击“获取”按钮时,它会因以下错误而崩溃:

执行doInBackground()时出错 java.lang.RuntimeException:java.lang.Throwable:在线程'AsyncTask#1'上调用了一个WebView方法。必须在同一个线程上调用所有WebView方法

这是我的MainActivity.java

package com.example.asyncts2;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.webkit.WebView;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

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

    button1 = (Button) findViewById(R.id.button1);
    button1.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {

              button1.setEnabled(false);
              DownloadWebPageTask task =  new DownloadWebPageTask();
              task.execute(new String[] {"http://www.google.com/"});
        }
    });
}

private class DownloadWebPageTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... urls) {
        WebView webView = (WebView) findViewById(R.id.webView1);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl(urls[0]);
        return "Done";
    }

    protected void onPostExecute(String result) {

        Toast.makeText(MainActivity.this, "result", Toast.LENGTH_SHORT).show();
    }
}

这是Log Cat错误

有人能指出我哪里出错了吗?非常感谢!

enter image description here

4 个答案:

答案 0 :(得分:1)

处理这种方法很简单,无论何时何地,只要您想访问或修改WebView,都可以在uithread中进行操作

runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                //shake the webView here!
                            }
                        });

答案 1 :(得分:1)

您不应使用AsyncTask在Webview中加载URL。如果要在加载完成时触发操作,请执行以下操作:

webView.setWebViewClient(new WebViewClient()
{
    public void onPageFinished(WebView view, String url)
    {
        // do something
    }
});

答案 2 :(得分:1)

doInBackground()方法不在UI线程中运行。它作为一个单独的线程运行,不会与UI交互。这就是为什么,它无法访问UI线程中存在的WebView。我真的没有看到在这里使用AsyncTask的目的。您可以在onClick方法本身中加载webview。否则,使用onPostExecute()方法更新Webview。

否则,正如@eduyayo所说,将runOnUiThread()方法放在doInBackground()方法中,并在run()方法中进行WebView更新。

答案 3 :(得分:1)

您必须在主线程中进行这些调用,即在您的活动内部。由于AsyncTask创建了另一个线程,因此android限制了很多操作。一个简单的方法是模仿回调处理程序。指导你的步骤,

创建界面:

public interface IWebViewHandler {
    void handleWebCall();
}

通过您的活动实现此interace并使用您的操作覆盖该方法,并从您的asynctask.doInBackground调用此方法,如

public class MainActivity extends Activity implements IWebViewHandler {

@Override
    public void handleWebCall() {
        //your work like action on WebViews
    /*    WebView webView = (WebView) findViewById(R.id.webView1);
        webView.getSettings().setJavaScriptEnabled(true);
        webView.loadUrl(urls[0]);*/

    }

    private class DownloadWebPageTask extends AsyncTask<String, Void, String> {

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

            return "Done";
        }

        protected void onPostExecute(String result) {

            Toast.makeText(MainActivity.this, "result", Toast.LENGTH_SHORT).show();
        }
    }

}

P.S:对handleWebCall的调用仅用于示例,修改调用方法和方法实现/签名。