Парсинг JSON. Получаем и разбираем JSON с внешнего ресурса


В этом уроке мы рассмотрим пример парсинга данных в формате JSON с внешнего ресурса, а также сделаем «разбор» полученных данных, чтобы достать нужную информацию.

Итак, у нас есть заготовочка в виде JSON по адресу — http://androiddocs.ru/api/friends.json

Выглядит это так:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
    "data": "dbfriends",
    "friends": [
        {
            "id": "1",
            "name": "Andrew",               
            "city": "Moscow",               
            "contacts": {
                "mobile": "+7 0000000",
                "email": "andrew@androiddocs.ru",
                "skype": "andrew"
            }
        },
        {
            "id": "2",
            "name": "Ivan",
            "city": "Kiev",
            "contacts": {
                "mobile": "+38 0000000",
                "email": "ivan@androiddocs.ru",
                "skype": "ivan"
            }
        }
    ]
}

Как видим, JSON содержит информацию о друзьях (friends), каждый из которых имеет собственные уникальные данные (id, имя, город, контакты).

Наша задача — считать этот JSON в строку и:
1. Получить имя второго друга (вывести в логи)
2. Перебрать всех друзей и вывести имя и контакты каждого из них

Решение этих двух задач должно помочь понять, как можно работать с данными в формате JSON.

Создадим LinearLayout без каких-либо вложенных элементов (всю информацию будем выводить в логи).

res/layout/activity_main.xml

1
2
3
4
5
6
7
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" />

Код MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package ru.androiddocs.jsonparse;
 
import android.os.AsyncTask;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
 
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
 
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
 
 
public class MainActivity extends ActionBarActivity {
 
    public static String LOG_TAG = "my_log";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        new ParseTask().execute();
    }
 
    private class ParseTask extends AsyncTask<Void, Void, String> {
 
        HttpURLConnection urlConnection = null;
        BufferedReader reader = null;
        String resultJson = "";
 
        @Override
        protected String doInBackground(Void... params) {
            // получаем данные с внешнего ресурса
            try {
                URL url = new URL("http://androiddocs.ru/api/friends.json");
 
                urlConnection = (HttpURLConnection) url.openConnection();
                urlConnection.setRequestMethod("GET");
                urlConnection.connect();
 
                InputStream inputStream = urlConnection.getInputStream();
                StringBuffer buffer = new StringBuffer();
 
                reader = new BufferedReader(new InputStreamReader(inputStream));
 
                String line;
                while ((line = reader.readLine()) != null) {
                    buffer.append(line);
                }
 
                resultJson = buffer.toString();
 
            } catch (Exception e) {
                e.printStackTrace();
            }
            return resultJson;
        }
 
        @Override
        protected void onPostExecute(String strJson) {
            super.onPostExecute(strJson);
            // выводим целиком полученную json-строку
            Log.d(LOG_TAG, strJson);
 
            JSONObject dataJsonObj = null;
            String secondName = "";
 
            try {
                dataJsonObj = new JSONObject(strJson);
                JSONArray friends = dataJsonObj.getJSONArray("friends");
 
                // 1. достаем инфо о втором друге - индекс 1
                JSONObject secondFriend = friends.getJSONObject(1);
                secondName = secondFriend.getString("name");
                Log.d(LOG_TAG, "Второе имя: " + secondName);
 
                // 2. перебираем и выводим контакты каждого друга
                for (int i = 0; i < friends.length(); i++) {
                    JSONObject friend = friends.getJSONObject(i);
 
                    JSONObject contacts = friend.getJSONObject("contacts");
 
                    String phone = contacts.getString("mobile");
                    String email = contacts.getString("email");
                    String skype = contacts.getString("skype");
 
                    Log.d(LOG_TAG, "phone: " + phone);
                    Log.d(LOG_TAG, "email: " + email);
                    Log.d(LOG_TAG, "skype: " + skype);
                }
 
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
    }
}

Класс Активити включает в себя один метод onCreate() и внутренний класс ParseTask, который является асинхронной задачей AsyncTask. В методе onCreate() мы запускаем данную задачу.

Класс ParseTask включает в себя два переопределенных метода doInBackground() и onPostExecute(). В первом мы запускаем фоновую задачу, которая получает данные с внешнего урла и возвращает JSON-строку методу onPostExecute(). В onPostExecute() мы парсим данные из JSON-объекта, предварительно создав его:

1
dataJsonObj = new JSONObject(strJson);

и выводим их в логи.

Тут нужно понимать разницу между JSONObject и JSONArray. Последний включает в себя несколько объектов JSONObject, т.о. мы разбираем его с помощью цикла. На каждой итерации цикла мы получаем объект JSONObject и уже можем доставать его отдельные свойства. Например, элемент «friends» является JSONArray, а вот каждый из составляющих его элементов — это JSONObject.

Добавим права доступа в интернет в файл манифеста:

1
<uses-permission android:name="android.permission.INTERNET"/>

После запуска приложения мы имеем такой результат в логах:

Получаем и разбираем JSON с внешнего ресурса

Комментариев: 14 на “Парсинг JSON. Получаем и разбираем JSON с внешнего ресурса

  1. andrey

    Спасибо, просто и понятно!

    Reply
  2. Drunk Panda

    Очень помог ваш пример с Google Calendar API

    Reply
  3. Геннадий

    Написал все по уроку, только вместил это все в активность фрагмента. и вроде без ошибок, кроме одной строчки! Строка new ParseTask().execute(); : unreachable statemen! Что это значит .И что я сделал не так? И можно еще вопрос. Как вывести информацию, скажем в листвью? Заранее спасибо.

    Reply
  4. Антон

    А как можно запихнуть эти данные в кеш?

    Reply
    1. admin Post author

      Думаю, это тема отдельной статьи. Возможно, в ближайшее время доберусь до нее. А пока — Google Вам в помощь:)

      Reply
  5. Iscron

    Спасибо, за отличный пример.

    Reply
  6. Anatoliy

    А как можно забрать данные только с «id»: «2″

    Reply
  7. Elena

    Спасибо большое за пример, хотелось бы узнать как вывести полученную информацию в листвью.

    Reply
    1. Роман

      Просто во время парса JSON вы добавляете все в список и при помощи адаптера выводите все.

      Reply
  8. Max

    Спасибо, коротко, ясно, всё по делу, отлично!

    Reply
  9. danek130995

    Спасибо Вам большое! Все работает!!

    Reply
  10. Иван

    а как например имейлы отобразить в ListView?

    Reply
  11. Andrew

    А как вызываются методы doInBackground() и onPostExecute()? Они же сами по себе не вызываются ведь, а в коде вызова нету.

    Reply
    1. admin Post author

      Вам не нужно об этом беспокоиться:) Это сделает за Вас система.

      Reply

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

*