0

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

我检查了浏览器中的 URL - 它工作正常。

我没有从 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我发现文档指出这是:当应用程序尝试在其主线程上执行网络操作时引发的异常。

由此我得出结论,我应该将我的电话放入AsyncTask.

谁能确认我正确理解了这一点-或者我在这里遗漏了什么?奇怪的是,我不得不这样catch (Throwable e)做才能查明真相。


进一步调查(05.22.2012):

我现在可以确认这个问题是由于应用程序尝试在其主线程上执行网络操作时引发的异常...。当我读到这篇文章时,它是从蜂窝开始的。

现在的问题:我收到来自雅虎的 301 响应(永久移动)。这很奇怪,因为当我将 URL 剪切粘贴到浏览器中时,它可以工作。

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


进一步调查(05.23.2012):

由于某种原因(在我的代码中)使用 Yahoo URI http://finance.yahoo.com/d/quotes.csv?s=时,响应是 301(永久移动)。当使用http://download.finance.yahoo.com/d/quotes.csv?s=时,响应为 200(OK)。即使两者在浏览器中都可以正常工作。我很幸运地找到了这个网页,它给了我一些关于雅虎对哪些 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 的一个错误。必须将&e=.csv添加到 URI 的末尾才能正常工作。就像这样: http: //download.finance.yahoo.com/d/quotes.csv ?s=KDHIX&f=sl1d1t1c1ohgv&e=.csv


最终代码

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

1 回答 1

1

您可能会得到一个Exception不是IOException. 然后,您的catch块永远不会被执行,并且您的finally块在该方法向retrieveStockFinParamsFromYahooApiUri.

您至少有 2 个选项:

  • 不要赶上一IOException堂课。尝试Throwable,打印堆栈跟踪,看看会发生什么。然后您可以稍后添加其他 catch 块来处理该案例。(捕捉Throwables是一种不好的编程习惯,但您可以暂时使用)。
  • 使用与上述相同的机制将调用retrieveStockFinParamsFromYahooApiUri置于 try catch 块中,以确定预期哪些异常类并相应地采取行动。

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

以下是一些其他建议:

于 2012-05-21T21:21:03.810 回答