如何在android asynctask中使用inputstream作为params?

时间:2013-04-20 12:14:38

标签: android android-asynctask

我正在制作一个Android应用程序来跟踪股票详情,我将通过csv(雅虎财经)检索数据。据我所知,在android 4.0中,无法在主线程上进行网络连接。因此,我将使用asynctask来建立连接。但是,我面临着一些问题。我想问一下输入流类型可以用作params吗?

public class StockDetails extends Activity {
    private InputStream is = null;
    private BufferedReader reader = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.stock_details);
        Intent i = getIntent();
        String stockNo = i.getStringExtra(MainActivity.STOCK_NO).toString();
        Log.i("Stock No", stockNo);
        String strURL = "http://download.finance.yahoo.com/d/quotes.csv?s="+ stockNo +".HK&f=nsl1opc1";
        Log.i("URL", strURL);
        class HostConnection extends AsyncTask<String, Void, InputStream> {
            private Exception ex;

            @Override
            protected void onPreExecute() {
                super.onPreExecute();
            }

            protected InputStream doInBackground(String... urls) {
                try {
                    // defaultHttpClient
                    DefaultHttpClient httpClient = new DefaultHttpClient();
                    HttpGet httpGet = new HttpGet(urls[0]);
                    HttpContext localContext = new BasicHttpContext();
                    HttpResponse httpResponse = httpClient.execute(httpGet, localContext);
                    HttpEntity httpEntity = httpResponse.getEntity();
                    return httpEntity.getContent();
                } catch (Exception e) {
                    this.ex = e;
                    return null;
                } 
            }
            @Override
            protected void onPostExecute(InputStream is) {
                super.onPostExecute(is);
                reader = new BufferedReader(new InputStreamReader(is));
            }
        }
        new HostConnection().execute(strURL);
        try {
            String line;
            while ((line = reader.readLine()) != null){
                String[] RowData = line.split(",");
                String name = RowData[0];
                String symbol = RowData[1];
                String currPrice = RowData[2];
                String open = RowData[3];
                String prevClose = RowData[4];
                String change = RowData[5];

                TextView stockName = (TextView)findViewById(R.id.stockName);
                stockName.setText(name);
                TextView stockSymbol = (TextView)findViewById(R.id.stockSym);
                stockSymbol.setText(symbol);
                TextView stockCurrPrice = (TextView)findViewById(R.id.currPrice);
                stockCurrPrice.setText(currPrice);
                TextView stockOpen = (TextView)findViewById(R.id.open);
                stockOpen.setText(open);
                TextView stockPrevClose = (TextView)findViewById(R.id.prevClose);
                stockPrevClose.setText(prevClose);
                TextView stockChange = (TextView)findViewById(R.id.change);
                stockChange.setText(change);
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        ...
    }

}

以上是我的代码,它无法执行语句return httpEntity.getContent();并跳转到异常部分。请帮忙。谢谢!

2 个答案:

答案 0 :(得分:1)

使用InputStream作为结果值类型是完全合法的,以及任何其他类。但是你必须意识到AsyncTask是异步执行的,所以如果你调用new HostConnection().execute(strURL);然后立即尝试使用AsyncTask中正在初始化的变量,你就会遇到麻烦。你应该等待AsyncTask通过定义某种回调机制来完成它的执行,或者在你的情况下,因为AsyncTask是一个内部类,你可以推送所有与{{{1}相关的代码。 1}}到BufferedReader

答案 1 :(得分:0)

如果您不想等待阅读整个输入流,直到onPostExecute被调用,请在doInBackground中阅读。

当您阅读重要结果时,通过实现onProgressUpdate将其发送回UI线程,但您可能应该在后台线程中处理InputStream而不是因此返回它,因为您可能遇到缓冲问题。