我如何解析URL请求的JSON结果?

时间:2017-08-17 19:47:24

标签: android json httpurlconnection

我是android和java的新手。我想得到一个url请求(结果是JSON)并解析它(例如从yahoo api获取JSON天气)。 我复制了getStringFromUrl函数,我知道我的函数错误(setWeather)。请帮帮我。

public static String getStringFromURL(String urlString) throws IOException {
    HttpURLConnection urlConnection;
    URL url = new URL(urlString);
    urlConnection = (HttpURLConnection) url.openConnection();
    urlConnection.setRequestMethod("GET");
    urlConnection.setReadTimeout(10000 /* milliseconds */);
    urlConnection.setConnectTimeout(15000 /* milliseconds */);
    urlConnection.setDoOutput(true);
    urlConnection.connect();
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(url.openStream()));
    char[] buffer = new char[1024];
    String outputString;
    StringBuilder builder = new StringBuilder();
    String line;
    while ((line = bufferedReader.readLine()) != null) {
        builder.append(line).append("\n");
    }
    bufferedReader.close();
    outputString = builder.toString();
    return outputString;
}

public void setWeather (View view) throws IOException, JSONException {
    String json = getStringFromURL("https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='Esfahan')&format=json");
    JSONObject jso = new JSONObject(json);
    JSONObject query = jso.getJSONObject("query");
    JSONObject result = query.getJSONObject("results");
    JSONObject channel = result.getJSONObject("channel");
    JSONObject windI = channel.getJSONObject("wind");
    JSONObject location = channel.getJSONObject("location");
    String last = "";
    last = location.getString("city");
    TextView tv = (TextView) findViewById(R.id.textView);
    tv.setText(last);
}

当我在设备应用程序崩溃时运行此应用程序时。 在Android监视器上写入是错误的:

2 个答案:

答案 0 :(得分:1)

在android的情况下,你必须遵循一个概念,所有时间的任务都需要在一个不阻塞你你的UI线程的单独线程上。并且所有IO调用或重度操作调用应该进入单独的线程。

有关如何进行网络操作的更多信息,请参阅Android开发人员指南 在这里(https://developer.android.com/training/basics/network-ops/connecting.html)并按照此文件。

答案 1 :(得分:1)

所有网络请求都应在单独的工作线程上进行,否则您将获得NetworkOnMainThread异常。对于您的用例,使用Asynctask,它具有方法doInBackground()来处理您在后台线程上的请求,并将结果发布回onPostExecute()方法内的主Ui线程。所以在doInBackground()方法中调用下面的方法。

getStringFromURL("https://query.yahooapis.com/v1/public/yql?q=select * from weather.forecast where woeid in (select woeid from geo.places(1) where text='Esfahan')&format=json");

并在onPostExecute()方法中使用像textview这样的ui组件

tv.setText(last);

在ui线程上运行。所有这些管理都是由Asnyctask完成的,因此您无需担心线程管理只知道要使用哪种方法。 Asynctask Android documentation