ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [안드로이드] 안드로이드에서 HTTP 연결하고 데이터 처리하기
    앱개발/안드로이드 앱 개발 2018. 3. 30. 12:21
    안드로이드-http-연결을-통해-데이터-받아오기.md

    안드로이드 http 연결을 통해 데이터 받아오기

    안드로이드에서는 String 에 저장된 url 주소를 통해 http/https 네트워크 통신으로 데이터를 쉽게 가져올 수 있는 api를 제공한다.

    String에 저장된 주소를 통해 실제 http 연결을 수행하기 위해서는 URL 클래스를 사용하고, 실제 네트워크 통신을 수행하기 위해서는 HttpURLConnection 클래스를 사용한다.

    연결된 네트워크에서 데이터를 받아와 처리하는데에는 InputStreamInputStreamReader를 사용한다. 두 클래스를 통해 받아온 데이터는 바이너리 데이터로 Human readable 하지 않다. 이를 human readable한 데이터 혹은 JSON 오브젝트로 변환하기 위해서는 BufferReader를 사용한다.

     

    사용가능한 URL로 변환하기

    아래의 예제 코드는 전부 안드로이드 스튜디오에서 테스트한 내용이며, 추가적인 코드는 생략한다. 전체코드는 본 문서의 최하단부 링크를 참조하기 바란다.

     
    private URL createURL(String stringUrl) {
      URL url = null;
      try{
        url = new URL(stringUrl);
      } catch (MalformedURLExceptino exception) {
        // 에러 처리 구문을 작성한다.
        return null; // createURL을 호출한 곳에서 null 처리가 필요하다. 
      }
      return url;
    }

    String에 저장된 주소값을 http 연결에 사용가능한 url 주소로 변환하는 과정은 간단하다. 위의 예제에서 처럼 URL 클래스를 사용하여, 생성자에 String을 전달하면 된다. URL 클래스 생성자는 MalformedURLException 예외가 발생할 수 있으므로 처리해야 한다.

     

    URL을 통해 Http 연결하기

    생성된 URLopenConnection() 메소드를 제공한다. 해당 메소드는 생성된 URL을 통해 실제 통신을 연결하기 위한 URLConnection 클래스를 반환한다. 아래의 예제를 통해 살펴보자

     
    xxxxxxxxxx
    private void connectAndGet(...) { // 연결을 수행할 함수의 최상된 임의 함수
      // .... 각종 처리 ...
      URL url = createURL(/*사용하고자 하는 주소 String*/);
      makeHttpRequest(url); // 실제 연결 수행
      // ... 추가 처리 ... 
    }
    private HttpURLConnection makeHttpRequest(URL url) throws IOException {
      if (url == null)
        return null; // 연결 불가능
      HttpURLConnection urlConnection = null;
      try {
        urlConnection = (HttpURLConnection) url.openConnection(); // 실제 연결을 수행할 오브젝트 생성
        urlConnection.setRequestMethod("GET"); // http 메소드 설정, get/post/put/delete
        urlConnection.setReadTimeOut(10000); // milliseconds 단위로 연결 이후 타임아웃 설정
        urlConnection.setConnectTimeOut(15000); // milliseconds 단위로 연결 시 타임아웃 설정
        urlConnection.connect(); // 실제 네트워크 연결 수행. 
        if (urlConnection.getResponseCode() != 200) {
          // 연결 응답 코드 200이 아닌경우: 연결 실패일때 추가 작업 수행
          throw IOException; 
        }
      } catch (IOException) {
        // 예외 처리 구간
      } finally {
        if (urlConnection != null) {
          urlConnection.disconnect();
        }
      }
      return urlConnection
    }

    URL 클래스의 openConnection() 메소드를 통해 URLConnection 오브젝트를 생성하여 실제 네트워크 연결을 수행한다. 연결에 필요한 메타 정보는 위의 예제에서 볼 수 있는 메소드 및 다양한 메소드로 설정 할 수 있다. 연결시 사용할 다양한 속성을 지정한 이후에는 URLConnection 및 자식 클래스들에서 제공하는 connect() 메소드를 사용해서 실제 연결을 수행한다. 이후 getResponseCode() 메소드를 통해 연결 성공 여부를 판별하고 추가작업을 수행하면 된다.

     

    InputStream을 통해 데이터 읽어들이기

    Http 연결이 되었으면 이제 데이터를 읽어올 차례이다. 연결에 에러가 없이 getResponseCode() 가 200임을 확인한 뒤에 진행을 해야하는것을 명심하자. URLConnection 클래스에서는 getInputStream() 메소드를 지원한다. 해당 메소드는 연결된 네트워크로부터 데이터를 읽어오는 메소드이다. 반환하는 오브젝트는 바이너리 형태로 데이터를 관리하는 InputStream 클래스이다. 아래 예제를 통해 살펴보자.

     
    x
    private void connectAndGet(...) { // 연결을 수행할 함수의 최상된 임의 함수
      // .... 각종 처리 ...
      URL url = createURL(/*사용하고자 하는 주소 String*/);
      HttpURLConnection urlConnection = makeHttpRequest(url); // 실제 연결 수행
      readFromStream(urlConnection);
      // ... 추가 처리 ... 
    }
    private void readFromStream(HttpURLConnection urlConnection) throws IOException{
      InputStream inputStream= urlConnection.getInputStream();
      StringBuilder output = new StringBuilder(); // 다중 문자열을 지속적으로 관리하기 위한 빌더
      if (inputStream != null) {
        // 캐릭터 셋 UTF-8 로 변환된 인풋 스트림
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
        BufferedReader reader = new BufferedReader(inputStreamReader); // 라인 별로 읽기 위한 변환
        String line = reader.readLine(); // 한줄을 읽어들임
        while(line != null) {
          // 버퍼에 데이터가 모두 소진 될때까지 읽어들임
          output.append(line); // 문자열 덧붙이기
          line = reader.readLine();
        }
      }
      return output.toString();
    }

    getInputStream() 메소드를 통해 가져온 InputStream은 바이너리 형태로 데이터 스트림을 관리하기 때문에, human readable 한 데이터로 변환 하기 위해 InputStreamReader를 사용하였다. 생성자의 2번째 매개변수로 Charset.forName('UTF-8')을 주어, 바이트 스트림을 UTF-8 캐릭터셋으로 해석된 문자열로 변환한다.

    변환된 문자열 데이터 스트림을 편하게 가공하기 위해서 BufferedReader를 사용하였다. 해당 클래스에서 제공하는 readLine() 메소드를 사용하면 한 줄씩 데이터를 읽을 수 있다. 이를 통해서 자신이 원하는 지점까지 데이터를 읽어 들인 후 하고자 하는 일을 수행하면 된다.

    예제에서는 데이터 스트림에 모든 데이터를 소진할 때까지 읽어 들인뒤 output 변수에 추가하고, 해당 데이터를 String으로 변환해서 반환하고 있다. 이후 반환된 String을 가지고 데이터 처리를 수행하면 된다.

    실제로 실행하고 확인 가능한 코드를 아래에 첨부하였으니 확인해보길 바란다. 해당 코드는 매우 짧은 코드이므로 코드 전체를 읽어보는 것도 좋을 것이다.

    Udacity 샘플 코드

    본 문서는 Udacity의 Android Basics: Networking 강의에서 발췌한 내용이다. 무료 강의로 훌륭한 안드로이드 개발 강의들을 제공하고 있다. 실제로 http 연결을 사용한 안드로이드 애플리케이션 예제의 전체코드는 아래의 링크를 통해 확인할 수 있다.

    실행 가능한 안드로이드 앱 샘플 코드

     

Designed by Tistory.