【问题标题】:HttpURLConnection with AsyncTask too slow (Android)带有 AsyncTask 的 HttpURLConnection 太慢(Android)
【发布时间】:2016-09-01 16:59:06
【问题描述】:

我尝试从互联网上获取数据并将它们保存在变量中,但是这个过程太慢了......这是我的代码:

`public class CurrConvert extends AsyncTask {

    boolean connection = true;

    float exchangeRate(final String currencyFrom, final String currencyTo) throws IOException {
        URL url = new URL("http://quote.yahoo.com/d/quotes.csv?s=" + currencyFrom + currencyTo + "=X&f=l1&e=.csv");
        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setUseCaches(false);
        InputStream inputStream = urlConnection.getInputStream();
        String result = IOUtils.toString(inputStream);
        return Float.parseFloat(result);
    }

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        pDialog = new ProgressDialog(getActivity());
        pDialog.setMessage(getContext().getString(R.string.updating));
        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected Object doInBackground(Object[] objects) {
        try {
            USD_AUD = exchangeRate("USD", "AUD");
            USD_CAD = exchangeRate("USD", "CAD");
            USD_EUR = exchangeRate("USD", "EUR");
            USD_GBP = exchangeRate("USD", "GBP");
            USD_INR = exchangeRate("USD", "INR");
            USD_JPY = exchangeRate("USD", "JPY");
            USD_SGD = exchangeRate("USD", "SGD");

            EUR_AUD = exchangeRate("EUR", "AUD");
            EUR_CAD = exchangeRate("EUR", "CAD");
            EUR_GBP = exchangeRate("EUR", "GBP");
            EUR_INR = exchangeRate("EUR", "INR");
            EUR_JPY = exchangeRate("EUR", "JPY");
            EUR_SGD = exchangeRate("EUR", "SGD");
            EUR_USD = exchangeRate("EUR", "USD");

            AUD_CAD = exchangeRate("AUD", "CAD");
            AUD_EUR = exchangeRate("AUD", "EUR");
            AUD_GBP = exchangeRate("AUD", "GBP");
            AUD_INR = exchangeRate("AUD", "INR");
            AUD_JPY = exchangeRate("AUD", "JPY");
            AUD_SGD = exchangeRate("AUD", "SGD");
            AUD_USD = exchangeRate("AUD", "USD");

            CAD_AUD = exchangeRate("CAD", "AUD");
            CAD_EUR = exchangeRate("CAD", "EUR");
            CAD_GBP = exchangeRate("CAD", "GBP");
            CAD_INR = exchangeRate("CAD", "INR");
            CAD_JPY = exchangeRate("CAD", "JPY");
            CAD_SGD = exchangeRate("CAD", "SGD");
            CAD_USD = exchangeRate("CAD", "USD");

            SGD_AUD = exchangeRate("SGD", "AUD");
            SGD_CAD = exchangeRate("SGD", "CAD");
            SGD_EUR = exchangeRate("SGD", "EUR");
            SGD_GBP = exchangeRate("SGD", "GBP");
            SGD_INR = exchangeRate("SGD", "INR");
            SGD_JPY = exchangeRate("SGD", "JPY");
            SGD_USD = exchangeRate("SGD", "USD");

            GBP_AUD = exchangeRate("GBP", "AUD");
            GBP_CAD = exchangeRate("GBP", "CAD");
            GBP_EUR = exchangeRate("GBP", "EUR");
            GBP_INR = exchangeRate("GBP", "INR");
            GBP_JPY = exchangeRate("GBP", "JPY");
            GBP_SGD = exchangeRate("GBP", "SGD");
            GBP_USD = exchangeRate("GBP", "USD");

            JPY_AUD = exchangeRate("JPY", "AUD");
            JPY_CAD = exchangeRate("JPY", "CAD");
            JPY_EUR = exchangeRate("JPY", "EUR");
            JPY_GBP = exchangeRate("JPY", "GBP");
            JPY_INR = exchangeRate("JPY", "INR");
            JPY_SGD = exchangeRate("JPY", "SGD");
            JPY_USD = exchangeRate("JPY", "USD");

            INR_AUD = exchangeRate("INR", "AUD");
            INR_CAD = exchangeRate("INR", "CAD");
            INR_EUR = exchangeRate("INR", "EUR");
            INR_GBP = exchangeRate("INR", "GBP");
            INR_JPY = exchangeRate("INR", "JPY");
            INR_SGD = exchangeRate("INR", "SGD");
            INR_USD = exchangeRate("INR", "USD");

        } catch (IOException e) {
            connection = false;
        }
        return 0;
    }

    @Override
    protected void onPostExecute(Object o) {
        super.onPostExecute(o);
        pDialog.dismiss();
        if (connection) {
            Toast.makeText(getContext(), "Done", Toast.LENGTH_LONG).show();
        } else {
            Toast.makeText(getContext(), R.string.no_connection, Toast.LENGTH_LONG).show();
        }
    }
}`

doInBackground 方法需要将近 30 秒才能完成该过程...有没有办法保持同步?

【问题讨论】:

  • 嗯,您正在下载一个 CSV,并将 56 个请求中的每一个都存储在内存中……您为什么希望这会很快?
  • 您可以加快速度,例如,不请求反向转换。如果您知道美元到欧元,那么您不需要查找欧元到美元。事实上,如果您对所有其他货币都了解一种货币,那么您应该能够应用一些数学来对其余货币进行转换。
  • @cricket_007 感谢您的建议!这样我总共有 7 个请求,所以我可以加快我的代码速度
  • 对于 JSON 格式的所有货币,我可能会选择以下答案。那将是一个请求。不建议在不必要时发出多个请求,因为它会更快耗尽电池

标签: java android android-asynctask httpurlconnection


【解决方案1】:

每次调用exchangeRate 方法时,都必须下载一个 csv 文件来提取汇率值。您总共有 56 个请求,这就是您的 AsyncTask 太慢的原因。

我的建议是使用这个链接:all currencies in JSON format

现在,很简单!只需解码 JSON 响应,您可以参考此链接:How to parse the Json response in android?

获取responses JSON Array,每个 JSON Object 的结构如下(示例):

{
"resource" : { 
"classname" : "Quote",
"fields" : { 
"change" : "-0.006400",
"chg_percent" : "-0.481094",
"name" : "USD/AUD",
"price" : "1.323900",
"symbol" : "AUD=X",
"ts" : "1472750677",
"type" : "currency",
"utctime" : "2016-09-01T17:24:37+0000",
"volume" : "0"
}
}
}

您现在要做的就是获取pricevalue,在您的情况下是汇率。

希望这会有所帮助:)

【讨论】:

  • 我是第一次面对JSON格式,我试着按照你的指示,希望这能解决我的问题:) ps:你建议我的链接的汇率,是实时的吗?
  • 是的,您从链接中获得的值是最新的!处理 json 很容易,至少你通过这个解决方案学到了一些新东西 ;)
  • 是的!我已经成功实现了 JSON ,感谢您解决了我的问题!
【解决方案2】:

AsyncTask 默认以较低的优先级运行,以帮助确保 UI 线程保持响应,但您可以更改它:

protected Void doInBackground() {
    Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
    // do your work
}

【讨论】:

  • 对我不起作用(同时完成代码)
猜你喜欢
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 2017-10-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多