使用AndroidHttpClient将无法正常工作

时间:2012-05-21 20:53:21

标签: android

我正在尝试使用AndroidHttpClient下载CSV文件。出于某种原因,它在"HttpResponse response httpClient.execute(httpGet, localContext);行中失败,只是转到"finally"

我已经在浏览器中检查了网址 - 它运行正常。

我从HttpResponse回复中得不到任何信息 - 它就像跳过它一样。

我不明白为什么。有什么想法吗?

由于 D

private ArrayList<String> retrieveStockFinParamsFromYahooApiUri(String yahooApiCall)
    {
        ArrayList<String> stockFinParamsFromYahooApiUriRows = new ArrayList<String>();
        String resultLine = "";

        BufferedReader reader = null;
        AndroidHttpClient httpClient = AndroidHttpClient.newInstance("yahooGetStockParams");
        HttpContext localContext = new BasicHttpContext();
        HttpGet httpGet = new HttpGet(yahooApiCall);

        try 
        {
            HttpResponse response = httpClient.execute(httpGet, localContext);              

            reader = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));

            while ((resultLine = reader.readLine()) != null) 
            {
                stockFinParamsFromYahooApiUriRows.add(resultLine);
            }
        }
        catch (IOException e) 
        {
            e.printStackTrace();
        } 
        finally 
        {
            if (reader != null) 
            {
                try 
                {
                    reader.close();
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }
            }
        }

        return stockFinParamsFromYahooApiUriRows;
    }

进一步调查(05.22.2012):

@Snicolas - 感谢您的评论。在我阅读你的评论后,我认为问题可能源于我使用模拟器而不是我的实际设备进行调试。我以为模拟器可能会遇到一些连接问题。当我在我的设备上测试它时 - 我发现问题仍然存在 - 所以这不是问题所在。

因此我按照您的建议将代码更改为catch (Throwable e)并获得以下堆栈快照:

05-22 18:17:41.457: W/System.err(24552): android.os.NetworkOnMainThreadException
05-22 18:17:41.461: W/System.err(24552):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1099)
05-22 18:17:41.461: W/System.err(24552):    at java.net.InetAddress.lookupHostByName(InetAddress.java:391)
05-22 18:17:41.461: W/System.err(24552):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:242)
05-22 18:17:41.465: W/System.err(24552):    at java.net.InetAddress.getAllByName(InetAddress.java:220)
05-22 18:17:41.465: W/System.err(24552):    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
05-22 18:17:41.465: W/System.err(24552):    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
05-22 18:17:41.468: W/System.err(24552):    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
05-22 18:17:41.468: W/System.err(24552):    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
05-22 18:17:41.468: W/System.err(24552):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
05-22 18:17:41.472: W/System.err(24552):    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
05-22 18:17:41.472: W/System.err(24552):    at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:257)
05-22 18:17:41.472: W/System.err(24552):    at com.bewildering.app.StournamentDbAdapter$YahooStocksParams.retrieveStockFinParamsFromYahooApiUri(StournamentDbAdapter.java:1536)
05-22 18:17:41.476: W/System.err(24552):    at com.bewildering.app.StournamentDbAdapter$YahooStocksParams.run(StournamentDbAdapter.java:1709)
05-22 18:17:41.476: W/System.err(24552):    at com.bewildering.app.StournamentActivity.onCreate(StournamentActivity.java:65)
05-22 18:17:41.476: W/System.err(24552):    at android.app.Activity.performCreate(Activity.java:4465)
05-22 18:17:41.476: W/System.err(24552):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)
05-22 18:17:41.480: W/System.err(24552):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1920)
05-22 18:17:41.480: W/System.err(24552):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1981)
05-22 18:17:41.480: W/System.err(24552):    at android.app.ActivityThread.access$600(ActivityThread.java:123)
05-22 18:17:41.484: W/System.err(24552):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1147)
05-22 18:17:41.484: W/System.err(24552):    at android.os.Handler.dispatchMessage(Handler.java:99)
05-22 18:17:41.484: W/System.err(24552):    at android.os.Looper.loop(Looper.java:137)
05-22 18:17:41.484: W/System.err(24552):    at android.app.ActivityThread.main(ActivityThread.java:4424)
05-22 18:17:41.488: W/System.err(24552):    at java.lang.reflect.Method.invokeNative(Native Method)
05-22 18:17:41.488: W/System.err(24552):    at java.lang.reflect.Method.invoke(Method.java:511)
05-22 18:17:41.488: W/System.err(24552):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-22 18:17:41.492: W/System.err(24552):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-22 18:17:41.492: W/System.err(24552):    at dalvik.system.NativeStart.main(Native Method)

在查找android.os.NetworkOnMainThreadException时,我发现the documentation表明这是:当应用程序尝试在其主线程上执行网络操作时引发的异常。

由此我得出结论,我应该将我的电话变成AsyncTask

任何人都可以确认我理解正确 - 或者我在这里遗漏了什么?奇怪的是,我要对catch (Throwable e)采取行动,以便深入了解这一点。


进一步调查(05.22.2012):

我现在可以确认这个问题是由于当应用程序尝试在其主线程上执行网络操作时抛出异常.... 我{{3}这开始于蜂窝。

现在出现问题:我收到雅虎的301回复(永久移动)。这很奇怪,因为当我将URL粘贴到浏览器中时,它可以正常工作。

知道为什么这应该在浏览器中工作但在应用程序中不起作用?我必须提到此HTTP请求接收CSV文件作为响应。这可能是一个问题吗?


进一步调查(05.23.2012):

出于某种原因,在使用(在我的代码中)Yahoo URI read时,响应是301(永久移动)。使用http://finance.yahoo.com/d/quotes.csv?s=时,响应为200(OK)。即便在浏览器中都可以正常工作。我很幸运地发现http://download.finance.yahoo.com/d/quotes.csv?s=给了我一些关于雅虎会对哪些URI做出反应的线索。现在我可以看到“阅读器”获取数据,一切都很好。我仍然得到一些奇怪的异常(仍然试图弄明白):在阅读了响应中的所有行后,我抓住了一个Throwable(我从之前的实验中留下了它),然后在堆栈中我得到了05-23 08:52:41.258: W/dalvikvm(933): threadid=11: thread exiting with uncaught exception (group=0x40a721f8)以及doInBackground(Void... params)中未捕获的异常。还在调查......

刚刚解决了这个问题 - 调用Yahoo API只是一个错误。必须在URI的末尾添加&amp; e = .csv 才能使其正常工作。就像那样:this web page


最终法典

private ArrayList<String> retrieveStockFinParamsFromYahooApiUri(String yahooApiCall)
    {
        ArrayList<String> stockFinParamsFromYahooApiUriRows = new ArrayList<String>();
        String resultLine = "";

        BufferedReader reader = null;
        AndroidHttpClient httpClient = AndroidHttpClient.newInstance("yahooGetStockParams");
        HttpContext localContext = new BasicHttpContext();
        HttpGet httpGet = new HttpGet(yahooApiCall);

        try 
        {
            HttpResponse response = httpClient.execute(httpGet, localContext);                  

            reader = new BufferedReader(new InputStreamReader(
                    response.getEntity().getContent()));

            while ((resultLine = reader.readLine()) != null) 
            {
                stockFinParamsFromYahooApiUriRows.add(resultLine);
            }

            if(response != null)
            {
                try
                {
                    response.getEntity().consumeContent();
                }
                catch (IOException e) 
                {
                    e.printStackTrace();
                }

            }
        }
        catch (IOException e) 
        {
            e.printStackTrace();                
        } 
        finally 
        {               
            if(httpClient != null)
            {
                httpClient.close();
            }

            if (reader != null) 
            {
                try 
                {
                    reader.close();
                } 
                catch (IOException e) 
                {
                    e.printStackTrace();
                }
            }
        }

        return stockFinParamsFromYahooApiUriRows;
    }

1 个答案:

答案 0 :(得分:1)

有可能你的Exception执行时不是IOException。然后,您的catch块永远不会被执行,并且在方法向finally的调用者抛出一个预期的异常之前执行retrieveStockFinParamsFromYahooApiUri块。

您至少有两个选项:

  • 不要抓住IOException,而是抓住一个前课。尝试Throwable,打印堆栈跟踪,看看会发生什么。然后你可以稍后添加其他catch块来处理这个案例。 (Catching Throwables is a bad programming practice,但你可以暂时使用。)
  • 使用与上面相同的机制将retrieveStockFinParamsFromYahooApiUri的调用置于try catch块中,以确定期望的异常类并采取相应的行动。

但是你需要优化对问题的理解,抓住一切可能,编写堆栈跟踪并检查logcat。

以下是其他一些建议: