반응형

오늘은 안드로이드에서 서버로부터 JSON 데이터를 읽어오는 방법에 대해서 소개 해드리겠습니다!

 

 

 

우선 설명에 앞서 대부분의 내용은 안드로이드 공식 레퍼런스

https://developer.android.com/reference/android/util/JsonReader을 참조했음을 미리 밝힙니다.

 

How to read JSON?

JsonReader Object는 JSON으로 인코딩 된 값을 토큰 스트림으로 읽습니다.

이 스트림에는 객체 및 배열의 시작 및 끝 구분 기호뿐만 아니라 리터럴 값(string, number, boolean, and null) 등이 모두 포함됩니다.

토큰은 JSON 문서에 나타나는 것과 같이 depth-first order 방식으로 방문합니다.

JSON 객체 내에서 {"name" : "value"} 쌍은 단일 토큰으로 함께 다루어집니다. 

 

How to import JsonReader?

JsonReader 클래스는 Object 클래스를 상속하여 Closeable 인터페이스를 구현한 클래스로,

android.util 패키지에 저장되어 있기 때문에 import 하실 때는

import android.util.JsonReader;

해주시면 되겠습니다.

 

How to parse JSON?

JsonReader 객체에는 Array를 다루는 메소드들과, Object를 다루는 메소드들이 나뉘어져 있습니다!

사실 JSON 데이터를 읽는 방법이 꼭 JsonReader 객체를 쓰는 방법만 있는 것은 아니지만, 이렇게 세분화된 JSON 데이터를 다룰 수 있는 기능이 있다는 것은 JsonReader의 굉장한 장점이라고 생각합니다.

 

1. 데이터 처리를 시작하기 전에 각각 다루고자 하는 데이터에 맞게 beginArray() 혹은 beginObject()를 호출하여 열기 괄호(배열의 경우 '[]', 객체의 경우 '{}')를 읽습니다.

2. 반복문을 통해 hasNext()가 false가 될 때까지 데이터 처리를 해줍니다.

3. 마지막으로 endArray() 혹은 endObject()를 호출하여 닫기 괄호를 읽습니다.

 

처리 과정 중에서 알 수 없는 name이 발견되면 예외가 발생하여 에러 처리가 됩니다.

이를 방지하기 위해 우리는 skipValue()를 호출하여 충돌을 피할 수 있습니다.

 

만약 값이 null일 경우에는, 먼저 peek()를 사용해 체크할 필요가 있습니다.

 

Example

우선 JSON 데이터를 설정합니다.

[
   {
     "id": 912345678901,
     "text": "How do I read JSON on Android?",
     "geo": null,
     "user": {
       "name": "android_newb",
       "followers_count": 41
      }
   },
   {
     "id": 912345678902,
     "text": "@android_newb just use android.util.JsonReader!",
     "geo": [50.454722, -104.606667],
     "user": {
       "name": "jesse",
       "followers_count": 2
     }
   }
 ]

 

 

그다음 안드로이드 개발환경에서 다음과 같이 메소드를 작성해줍니다.

 

public List<Message> readJsonStream(InputStream in) throws IOException {
     JsonReader reader = new JsonReader(new InputStreamReader(in, "UTF-8"));
     try {
       return readMessagesArray(reader);
     } finally {
       reader.close();
     }
   }

   public List<Message> readMessagesArray(JsonReader reader) throws IOException {
     List<Message> messages = new ArrayList<Message>();

     reader.beginArray();
     while (reader.hasNext()) {
       messages.add(readMessage(reader));
     }
     reader.endArray();
     return messages;
   }

   public Message readMessage(JsonReader reader) throws IOException {
     long id = -1;
     String text = null;
     User user = null;
     List<Double> geo = null;

     reader.beginObject();
     while (reader.hasNext()) {
       String name = reader.nextName();
       if (name.equals("id")) {
         id = reader.nextLong();
       } else if (name.equals("text")) {
         text = reader.nextString();
       } else if (name.equals("geo") && reader.peek() != JsonToken.NULL) {
         geo = readDoublesArray(reader);
       } else if (name.equals("user")) {
         user = readUser(reader);
       } else {
         reader.skipValue();
       }
     }
     reader.endObject();
     return new Message(id, text, user, geo);
   }

   public List<Double> readDoublesArray(JsonReader reader) throws IOException {
     List<Double> doubles = new ArrayList<Double>();

     reader.beginArray();
     while (reader.hasNext()) {
       doubles.add(reader.nextDouble());
     }
     reader.endArray();
     return doubles;
   }

   public User readUser(JsonReader reader) throws IOException {
     String username = null;
     int followersCount = -1;

     reader.beginObject();
     while (reader.hasNext()) {
       String name = reader.nextName();
       if (name.equals("name")) {
         username = reader.nextString();
       } else if (name.equals("followers_count")) {
         followersCount = reader.nextInt();
       } else {
         reader.skipValue();
       }
     }
     reader.endObject();
     return new User(username, followersCount);
   }

 

위와 같이 메소드를 작성하시고 테스트해 보신다면 Message 객체에 전송받은 JSON 데이터가 잘 들어갔음을 확인하실 수 있을겁니다.

 

여기서 눈여겨 보실 부분은 NextInt()인데요, JsonReader를 사용한 방식이 아닌 대부분의 JSON Data reading 방식은 스트림을 문자열로 전환하여 JSON으로 파싱해주는 작업을 거쳐, 숫자 데이터를 다루기 위해서는 String type을 불가피하게 거쳐야만 했는데 JsonReader에서는 number format도 직관적으로 다룰 수 있다는 것이 특징입니다.

 

이상으로 JsonReader에 대해 알아보았습니다:)

 

 

 

반응형
반응형