AsyncTask doInBackground返回多个字符串

时间:2016-12-19 21:10:18

标签: java android android-asynctask

我试图在android studio中构建一个非常基本的天气应用程序。我正在使用AsyncClass返回多个字符串。

正如您在代码中看到的,我使用了一个名为" Wrapper"的类。用于存储我的字符串,所以我可以返回一个类对象,并在AsyncTask的onPostExecute方法中使用它。我面临的问题是,当我测试应用程序时,所有返回的Stringsshow都是未定义的(Wrapper类的默认值)。这意味着字符串没有在doInBackground方法中更新,我似乎无法找出原因!

My Activity

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Log.i(MainActivity.class.getSimpleName(), "Can't connect to Google Play Services!");
    }
    private class Wrapper
    {
          String Temperature = "UNDEFINED";
         String city = "UNDEFINED";
         String country = "UNDEFINED";
    }

    private class GetWeatherTask extends AsyncTask<String, Void, Wrapper> {
        private TextView textView;

        public GetWeatherTask(TextView textView) {
            this.textView = textView;
        }

        @Override
        protected Wrapper doInBackground(String... strings) {
            Wrapper w = new Wrapper();
            String Temperature = "x";
            String city = "y";
            String country = "z";

            try {
                URL url = new URL(strings[0]);
                HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

                InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
                StringBuilder builder = new StringBuilder();

                String inputString;
                while ((inputString = bufferedReader.readLine()) != null) {
                    builder.append(inputString);
                }

                JSONObject topLevel = new JSONObject(builder.toString());
                JSONObject main = topLevel.getJSONObject("main");
                JSONObject cityobj = topLevel.getJSONObject("city");
                Temperature = String.valueOf(main.getDouble("temp"));
                city = cityobj.getString("name");
               country = cityobj.getString("country");

                w.Temperature= Temperature;
                w.city= city;
                w.country=country;

                urlConnection.disconnect();
            } catch (IOException | JSONException e) {
                e.printStackTrace();
            }
            return w;
        }

        @Override
        protected void onPostExecute(Wrapper w) {
            textView.setText("Current Temperature: " + w.Temperature + " C" + (char) 0x00B0
                       +"\n" + "Current Location: "+ w.country +"\n" + "City: "+  w.city );
        }
    }
}

更新

原来我在我的代码中使用了错误的网址,我正在使用: http://api.openweathermap.org/data/2.5/weather?lat=%f&lon=%f&units=%s&appid=%s

相反,我应该一直在使用:

http://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&units=%s&appid=%s

-aka而不是天气我应该使用预测

3 个答案:

答案 0 :(得分:1)

在研究了你的代码之后,你的try块失败了,它正在返回你的对象,但是空了,或者你的JSON解析有问题。如果你能向我们展示你试图解析的JSON,那将是一个很大的帮助。

话虽如此,它仍然显示为“UNDEFINED”的事实是因为这是你初始化它的方式,并且因为(JSON解析可能失败),对象将以未编辑状态返回。

修改

您正在解析JSON错误。您正试图在顶层目录中找到一个名为“main”的对象,但是主对象只存在于名为list的数组中!

请在此处查看更易于查看和直观的表示:http://prntscr.com/dlhlrk

您可以使用此站点来帮助可视化您的JSON并根据它创建适当的解决方案。 https://jsonformatter.curiousconcept.com/

答案 1 :(得分:1)

查看之前发布的API(api.openweathermap.org),您正在尝试访问不存在的变量。我建议你看看API returns是什么,如果你得到一个JSONException,我会逐个尝试获取变量

编辑: 你在用什么API?在您的帖子中,您说它是http://api.openweathermap.org/data/2.5/weather,但在上面的评论中,您说它是http://api.openweathermap.org/data/2.5/forecast

如果您使用的是天气API(如最初所述),您可以使用以下内容:

    @Override
    protected Wrapper doInBackground(String... strings) {
        Wrapper w = new Wrapper();

        try {
            URL url = new URL(strings[0]);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

            InputStream stream = new BufferedInputStream(urlConnection.getInputStream());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(stream));
            StringBuilder builder = new StringBuilder();

            String inputString;
            while ((inputString = bufferedReader.readLine()) != null) {
                builder.append(inputString);
            }

            Log.d("JSON", builder.toString());

            JSONObject topLevel = new JSONObject(builder.toString());
            JSONObject main = topLevel.getJSONObject("main");
            JSONObject sys = topLevel.getJSONObject("sys");

            w.Temperature = String.valueOf(main.getDouble("temp"));
            w.city = topLevel.getString("name");
            w.country = sys.getString("country");

            urlConnection.disconnect();
        } catch (IOException | JSONException e) {
            e.printStackTrace();
        }
        return w;
    }

答案 2 :(得分:1)

您的错误从此处开始

JSONObject main = topLevel.getJSONObject("main");

可能是因为topLevel对象没有"main"键。

{  
   "city":{  },
   "cod":"200",
   "message":0.1859,
   "cnt":40,
   "list":[  ]
}

将你的JSON扔到这里。 https://jsonformatter.curiousconcept.com/

您会注意到"main"元素中有许多"list"个密钥,但您必须解析从getJSONArray("list")开始的密钥。

基本上,就像这样

String city = "undefined";
String country = "undefined";
List<Double> temperatures = new ArrayList<Double>();

try {
    JSONObject object = new JSONObject(builder.toString());
    JSONObject jCity = object.getJSONObject("city");
    city = jCity.getString("name");
    country = jCity.getString("country");

    JSONArray weatherList = object.getJSONArray("list");
    for (int i = 0; i < weatherList.length(); i++) {
        JSONObject listObject = weatherList.getJSONObject(i);
        double temp = listObject.getJSONObject("main").getDouble("temp");
        temperatures.add(temp);
    }

} catch (JSONException e) {
    e.printStackTrace();
}

return new Wrapper(city, country, temperatures);