使用JSoup和AsyncTask访问URL&总是在doInBackground()中抛出异常

时间:2014-07-22 13:41:15

标签: java android exception android-asynctask jsoup

我正在尝试从http://www.gasbuddy.com/GB_Price_List.aspx提取文本并在TextView中设置该文本。

当我致电

    try {
        Document document = Jsoup.connect(URL).get();

        // selector query
        Element gasPrice = ((Element) document).select(
                "table.listing > tbody > tr > td.p").first();
            Log.d("getData", gasPrice.text().toString());
            results = gasPrice.text().toString();
        } catch (Exception e) {
        Log.e("Darrell", "EXCEPTION IN DOINBACKGROUND()", e);
        e.printStackTrace();
    }

它总是被抓住......

这里是AsyncTask():

private class InternetGasBuddyConnection extends
        AsyncTask<String, String, String> {

    protected String doInBackground(String... arg0) {

        runOnUiThread(new Runnable() {
            public void run() {
                try {
                    Document document = Jsoup.connect(URL).get();

                    // selector query
                    Element gasPrice = ((Element) document).select(
                            "table.listing > tbody > tr > td.p").first();

                    Log.d("getData", gasPrice.text().toString());

                    results = gasPrice.text().toString();

                } catch (Exception e) {
                    Log.e("Darrell", "EXCEPTION IN DOINBACKGROUND()", e);
                    e.printStackTrace();
                }
            }
        });

        return results;
    }

    public void onPostExecute(String result) {
        travelCostView.setText(result);
    }
}

static final String URL = "http://www.gasbuddy.com/GB_Price_List.aspx";是我尝试访问的网址

logcat的

07-22 14:20:56.941: W/IInputConnectionWrapper(8471): showStatusIcon on inactive InputConnection
07-22 14:21:02.497: W/ApplicationPackageManager(8471): getCSCPackageItemText()
07-22 14:21:02.587: D/Darrell(8471):  
07-22 14:21:02.607: E/Darrell(8471): EXCEPTION IN DOINBACKGROUND()
07-22 14:21:02.607: E/Darrell(8471): android.os.NetworkOnMainThreadException
07-22 14:21:02.607: E/Darrell(8471):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1156)
07-22 14:21:02.607: E/Darrell(8471):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
07-22 14:21:02.607: E/Darrell(8471):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
07-22 14:21:02.607: E/Darrell(8471):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89)
07-22 14:21:02.607: E/Darrell(8471):    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:439)
07-22 14:21:02.607: E/Darrell(8471):    at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:424)
07-22 14:21:02.607: E/Darrell(8471):    at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:178)
07-22 14:21:02.607: E/Darrell(8471):    at org.jsoup.helper.HttpConnection.get(HttpConnection.java:167)
07-22 14:21:02.607: E/Darrell(8471):    at com.example.fuelcalculator.FuelEconomyCalculatorActivity$InternetGasBuddyConnection$1.run(FuelEconomyCalculatorActivity.java:300)
07-22 14:21:02.607: E/Darrell(8471):    at android.os.Handler.handleCallback(Handler.java:733)
07-22 14:21:02.607: E/Darrell(8471):    at android.os.Handler.dispatchMessage(Handler.java:95)
07-22 14:21:02.607: E/Darrell(8471):    at android.os.Looper.loop(Looper.java:157)
07-22 14:21:02.607: E/Darrell(8471):    at android.app.ActivityThread.main(ActivityThread.java:5356)
07-22 14:21:02.607: E/Darrell(8471):    at java.lang.reflect.Method.invokeNative(Native Method)
07-22 14:21:02.607: E/Darrell(8471):    at java.lang.reflect.Method.invoke(Method.java:515)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-22 14:21:02.607: E/Darrell(8471):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-22 14:21:02.607: E/Darrell(8471):    at dalvik.system.NativeStart.main(Native Method)
07-22 14:21:02.607: W/System.err(8471): android.os.NetworkOnMainThreadException
07-22 14:21:02.607: W/System.err(8471):     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1156)
07-22 14:21:02.607: W/System.err(8471):     at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
07-22 14:21:02.607: W/System.err(8471):     at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
07-22 14:21:02.607: W/System.err(8471):     at java.net.InetAddress.getAllByName(InetAddress.java:214)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.Dns$1.getAllByName(Dns.java:28)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:216)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:122)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:292)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.HttpEngine.sendSocketRequest(HttpEngine.java:255)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:206)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:345)
07-22 14:21:02.607: W/System.err(8471):     at com.android.okhttp.internal.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:89)
07-22 14:21:02.607: W/System.err(8471):     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:439)
07-22 14:21:02.607: W/System.err(8471):     at org.jsoup.helper.HttpConnection$Response.execute(HttpConnection.java:424)
07-22 14:21:02.607: W/System.err(8471):     at org.jsoup.helper.HttpConnection.execute(HttpConnection.java:178)
07-22 14:21:02.607: W/System.err(8471):     at org.jsoup.helper.HttpConnection.get(HttpConnection.java:167)
07-22 14:21:02.607: W/System.err(8471):     at com.example.fuelcalculator.FuelEconomyCalculatorActivity$InternetGasBuddyConnection$1.run(FuelEconomyCalculatorActivity.java:300)
07-22 14:21:02.607: W/System.err(8471):     at android.os.Handler.handleCallback(Handler.java:733)
07-22 14:21:02.617: W/System.err(8471):     at android.os.Handler.dispatchMessage(Handler.java:95)
07-22 14:21:02.617: W/System.err(8471):     at android.os.Looper.loop(Looper.java:157)
07-22 14:21:02.617: W/System.err(8471):     at android.app.ActivityThread.main(ActivityThread.java:5356)
07-22 14:21:02.617: W/System.err(8471):     at java.lang.reflect.Method.invokeNative(Native Method)
07-22 14:21:02.617: W/System.err(8471):     at java.lang.reflect.Method.invoke(Method.java:515)
07-22 14:21:02.617: W/System.err(8471):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
07-22 14:21:02.617: W/System.err(8471):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
07-22 14:21:02.617: W/System.err(8471):     at dalvik.system.NativeStart.main(Native Method)

我的Manifest中包含互联网,所以我知道这不是问题。

这里的大问题是......为什么,当我运行程序并且它到达doInBackground()中的上述try-catch块时,它总是被捕获。

为什么这段代码不起作用?

    Document document = Jsoup.connect(URL).get();

    // selector query
    Element gasPrice = ((Element) document).select(
            "table.listing > tbody > tr > td.p").first();
        Log.d("getData", gasPrice.text().toString());
        results = gasPrice.text().toString();

1 个答案:

答案 0 :(得分:1)

虽然对问题的评论绝对有效并且指出了真正的问题,但我仍然想澄清为什么会发生这种情况。问题是,JSoup的调用Jsoup.connect(URL).get();是一个同步调用。它阻塞调用线程,直到从远程服务器获取数据。如果您碰巧通过某个按钮点击处理程序或活动的启动进行该调用,您将面临此错误。

Android中有多种技术可以解决这个问题。创建一个AsyncTask实例肯定是其中之一,因为它不仅需要在后台进行调用(使用SingleThreadExecutor),还要确保解析的结果将被传递到UI线程(这一点很重要,因为你最有可能想要将它们显示给用户)。您可以在此处找到有关如何正确实现AsyncTask的信息:http://developer.android.com/reference/android/os/AsyncTask.html