[NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

170
ANDROID - DAY 4 Network 라는 비에 취해 보다..
  • date post

    20-Oct-2014
  • Category

    Technology

  • view

    2.369
  • download

    9

description

NEXTGRAM 만들기 4일차 - Networking , JSON Written by 정문철 Reviewed by 손영수

Transcript of [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Page 1: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

ANDROID����������� ������������������  -����������� ������������������  DAY����������� ������������������  4����������� ������������������  Network����������� ������������������  라는����������� ������������������  비에����������� ������������������  취해����������� ������������������  보다..

Page 2: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

학습목표이 학습을 마치면…

-HttpURLConnection을 사용하여 서버의 데이터를 다운로드 할 수 있습니다. !-스레드를 사용하여 시간이 걸리는 작업을 비동기로 처리할 수 있습니다. !-디바이스 내의 사진을 불러올 수 있습니다. !-ProgressDialog를 사용할 수 있게 됩니다. !-안드로이드 생명주기에 대한 형태를 간략하게나마 알 수 있습니다.

Page 3: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이때까지 작업한 내용

Page 4: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이때까지 HTML로 구현한 게시판을 안드로이드 플랫폼에서 다시 구현

Page 5: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

DB의 데이터를 Adapter를 사용하여

리스트로 표현하였습니다.

Page 6: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

하지만 아직 네트워킹이 준비가 되질 않아 아무런 데이터도 서버로부터 받는것이 없었습니다.

Page 7: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

네 트 워 크이번에 구현 할 내용

(HTTP 통신)

Page 8: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

서버로부터 게시글의 정보를 가져와야하고…

Page 9: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

글쓰기 버튼을 눌러 사진을 선택하고 글을 쓰면 서버에 게시글이 업로드가 되고

리스트에 다시 반영이 된다.

Page 10: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

먼저 테스트코드로 파싱하던 JSON데이터를 서버로부터 받아오도록 하겠습니다.

Page 11: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

서버로부터 게시글의 정보를 json 형태로 불러오기

Page 12: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

기존의 수업에서 사용하시던 서버를 이용하시면 자신의 데이터에 맞게 예제를 변형하면서 진행하시면 됩니다.

Page 13: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이제 안드로이드 NEXTAGRAM을 마저 만들어 보겠습니다.

Page 14: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

앞으로 구현해야 될 내용은…

Page 15: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

1)데이터 요청

2)서버로 부터JSON으로 데이터 받음

크게 나누어서 Proxy 클래스를 만들어 JSON데이터를 받는 부분과

Page 16: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

7)Dao로 부터 가져온 데이터를 리스트에 표시

ArticleWrite8)글 입력 창으로 이동 9)글 제목,내용, 사진 경로등을 전달

10)post방식으로 서버에 사진 전송

ProxyUP 클래스를 만들어 서버에 사진과 게시글 정보를 보내는 부분이 필요합니다.

Page 17: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

필요한 공통점은 HTTP통신…

Page 18: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

HTTP 클라이언트가 애플리케이션 개발의 중심이라고도 할 정도로 Android 애플리케이션에서는 HTTP 통신을 다루는 부분의 비중이 큽니다.

네트워크가 없는 안드로이드 앱은 뭔가 빠진 듯한…

(돈버는 앱들은 다 네트워크가 있습니다!!!)

Page 19: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

HTTP 클라이언트 개발을 위해 Android SDK에서 제공하는 API를 사용하거나 오픈 소스 라이브러리를 활용하기도 하는 등

클래스 선택의 폭도 굉장히 많습니다.

Page 20: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Android의 HTTP 클라이언트 라이브러리 http://helloworld.naver.com/helloworld/377316

안드로이드가 HTTP 통신을 개발하기에 좋은 환경 같지만 불편한 점들이 많습니다.

Page 21: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이 예제에서는 Android 개발팀이 권고한 HttpURLConnection을 사용합니다.

!하지만 오히려 다른 방법에 비해 사용하기 복잡 할 수 있습니다. 다른 방법을 사용하고 싶으신 분은 다른 API나 라이브러리를

이용하여 구현할 수 있습니다. !

(단 사진을 post방식으로 업로드 하는 부분이 있으므로 사용하실려는 방법의 업로드 방식을 참고 후 선택하시길 권장합니다.)

http://android-developers.blogspot.kr/2011/09/androids-http-clients.html

Page 22: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

먼저 DB에 넣을때 사용했던 JSON테스트 데이터를 대신하여 서버로부터 데이터를 다운받도록 하겠습니다.

삭제예정!

Page 23: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Proxy라는 클래스를 하나 생성합니다.

Page 24: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

PROXY란?디자인 패턴중에 나오는 용어로

마치 내 컴퓨터에 있는 클래스 같이 호출하는 것을 의미합니다. !

위치 투명성 Location Transparency 를 제공합니다 !

Page 25: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

또한 MARSHLLER/UNMARSHALLER !

marshalling/unmarshalling이라는 것은 데이터를 변환해서 주고 받는 거에요.

!네트워크에서 배운 encoding/decoding과 동일한 개념이에요.

!

Page 26: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

전에 MainActivity에서 테스트 JSON형태의 String을 받아 Dao에 넘겨줬던 것처럼 String을 반환하는 함수를 만듭니다.

Page 27: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

접속할 서버주소 로 URL 인스턴스를 만들고 HttpURLConnection에서

연결을 만들어 줍니다. (Try Catch 포함!)

자신의 서버 주소에 맞게 수정!

Page 28: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

연결시의 Request Header정보를 설정해 주고 connect();로 연결을 합니다.

Page 29: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

어디서 많이 보던 내용…https://leansys.com/download/networks/lec11.pdf네트워크 11주차 김종규

Page 30: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

미리보는 패킷 분석 내용… (By Wireshark)

Response

Request

Page 31: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

그리고 getResponseCode()로 ResponseCode를 받아온 후 switch문을 이용하여 정상적으로 데이터를 받은 상태

(200,201)를 구분하여 줍니다.

Page 32: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

어디서 많이 보던 내용…https://leansys.com/download/networks/lec11.pdf네트워크 11주차 김종규

Page 33: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

InputStreamReader와 BufferdReader를 이용하여 데이터를 받은 후 리턴을 해줍니다.

Page 34: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

과제가 아닙니다!!생각해 봅시다.(Advanced를 위한)

ResponseCode가 200대가 아니면 null을 리턴해 버립니다.

어떻게 처리하는것이 좋을까요? 또 200이여도 빈 값이 오면 어떻게 될까요?

Page 35: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

저번주에 MainActivity에서 테스트 함수로부터 JSON데이터를 가지고 왔습니다.

하지만 이번에는 아까 만든 Proxy로부터 서버에 접속하여 데이터를 가져오겠습니다.

Page 36: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Proxy 인스턴스를 만들고 좀 전에 만든 함수를 통해 서버의 데이터를 가져온 후 Dao에게 넘겨줍니다.

Page 37: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

다 잘 된것 같지만 지금 테스트를 하면 “permission denied” 라면서

앱이 오류가 나서 종료되어버립니다…

Page 38: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

안드로이드에서 네트워크를 사용하려면 앱 설정에 따로 권한을 받아야합니다.

Page 39: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

안드로이드에서는 앱마다 사용할 수 있는 권한을 명시하고

!사용자가 권한을 확인 할 수

있도록 합니다. !

앱은 명시되지 않은 권한에 관련된 작업은 사용이 제한됩니다.

Page 40: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

프로젝트에서 AndroidManifest.xml을 편집하여 <uses-permission android:name="android.permission.INTERNET" />을

추가합니다.

Page 41: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

그래도 앱이 오류나서 종료되요!!!

Page 42: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

로그캣을 보겠습니다…

Page 43: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

NetworkOnMainThreadException… !

한때 준비안된 안드로이드 개발자들에게 멘붕을 안겨줬던 전설의?! 오류입니다.

!

안드로이드 버젼 3.0이상부터 발생한 에러로 간단히 설명하자면 네트워크 작업은

별도의 스레드에서 작업하라! 라는 의미입니다.

Page 44: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

NetworkOnMainThreadException이 발생한 이유?!

구글은 생각하였습니다.

안드로이드가 iPh●ne에 비해 앱이 느리다고 하는데

주로 개발자가 잘못 만들어서라고!

이 이야기는 픽션입니다!

Page 45: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

http://ui.nhnnext.org/crong/scope/android/week4/ThreadTest.apk

메인스레드 (onCreate)안에서 네트워킹 작업을 하면

연결이 끝난 후에 화면이 표시됩니다.테스트앱

2초후에 화면을 볼 수 있습니다.

Page 46: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

사실은 네트워크 로딩중…

앱을 켰는데 멈춰 버렸잖아!!

Page 47: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

하지만 스레드를 사용하면 미리 화면을 표시하고

네트워크 작업을 할 수 있습니다.

0.2초만에 먼저 화면을 볼 수 있습니다.

Page 48: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

구글은 생각하였습니다.

아무리 스레드를 쓰라고 권고해도 개발자들이 말을 듣지 않잖아! 아예 스레드를 안쓰면 앱이 실행도 안되게 만들면

개발자들이 스레드를 쓰겠지

그래서 3.0부터 멀쩡했던 코드가 안돌아가고 개발자들은 멘붕에 빠졌었습니다…

인터넷을 돌아다니다 보이는 코드들이 예전에 만들어진 것들은 이 문제로 인해 돌아가지 않는 경우가 많습니다.

Page 49: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

해결방법!

- 안드로이드 버젼을 낮춘다. !

- 앱이 종료되지 않도록 메인스레드에서의 네트워킹을 허용하는 코드를 넣는다. !

- 스레드를 사용한다!

Page 50: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

사실… 좀… 너무… 좋치 않은 방법 사용하지 마세요…

안드로이드 버젼을 낮춘다.(비추)

Page 51: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

회피 코드를 넣는다.

StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().permitNetwork().build());

메인에 다음과 같은 코드를 넣습니다.

하지만 바람직한 방법은 아니니 테스트용도나 어쩔수 없는 경우에만 사용해주세요

Page 52: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

스레드를 사용한다!

보통 AsyncTask를 많이 사용하지만 이 예제에서는 간단히 스레드를 만들어서 사용합니다.

Page 53: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

NEXTAGRAM에도 적용해 보겠습니다.

Page 54: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

하지만 그전에 스레드로 만들기 쉽도록 약간의 정리정돈을 하겠습니다.

Page 55: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

지금 메인에 너무 많은 것들이 한번에 다 적혀있습니다.

서버로부터 JSON 데이터를 가져와서 DB에 넣는 부분

DB로부터 게시글 데이터를 가져와서 리스트에 넣는 부분

Page 56: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

refreshData라는 함수를 하나 만들어 코드를 옮겼습니다.

Page 57: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

마찬가지로 리스트와 관련된 listView라는 함수를 하나 만들어 코드를 옮겼습니다.

Dao를 전역으로 공통으로 써도 좋습니다…

Page 58: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이제 이 refreshData()함수에 스레드를 달아보겠습니다.

Page 59: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Thread를 생성하고 start()하면 끝입니다…

Page 60: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

바로 DB에 집어 넣는것을 끝내면 listView()를 호출하여 리스트를 표현해주고 싶지만

!

바로 밑에서 호출을 하면 오류가 발생합니다.

Page 61: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

왜냐하면 스레드에서 바로 메인UI의 접근이 제한되어 있기 때문입니다.

!

그래서 Handler라는 것을 만들고 그 안에서 listView()를 호출합니다.

Page 62: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

1)데이터 요청

2)서버로 부터JSON으로 데이터 받음

3)서버로부터 받은 데이터를 전달

이제 서버로부터 JSON을 받아 메인에 보내서 사용하는것까지 완료되었습니다.

Page 63: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

하지만 JSON은 다운 받았는데 서버에 있는 사진 파일은 다운로드를 받고 있지를 못하고 있습니다.

!다운로드를 처리를 해주기 위한 새 클래스를 또 만들어 보겠습니다.

Page 64: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

서버로부터 파일(사진)을 다운받는 클래스 만들기

FILE

Page 65: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Proxy클래스와 거의 동일합니다. 하지만 파일을 다운 받는 클래스를 따로 만들어 놓으면

다른 개발을 할 때에도 여러모로 편리하므로 별도의 FileDownloader클래스를 만들어 보겠습니다.

Page 66: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이 예제에서는 FileOutputStream openFileOutput을 사용하여 /data/data/<package_name>/files/<파일>

경로에 저장을 합니다. !

따로 WRITE_EXTERNAL_STORAGE 권한이 필요없으나 !

파일을 확인하기 위해서는 루팅이 안되어 있는 디바이스에서는 data폴더에 접근을 하지 못합니다.

!다운을 받은 파일을 보고 싶으시면

루팅이 되어있는 디바이스, 제니모션(AVD)상에서 확인이 가능 합니다.

Page 67: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

FileDownloader클래스를 만들고 생성자로 Context를 받아 보관합니다.

Page 68: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

파일을 받을 주소와 저장 할 이름을 받는 함수를 만들고 File에 context.getFilesDir().getPath() + "/" + fileName로

파일을 저장할 경로를 구합니다.

Page 69: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

if (!filePath.exists()) { }를 이용하여 파일이 경로에 ‘없을’ 때에만 다운로드를 받도록 합니다.

Page 70: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

JSON데이터를 받을때 처럼 HttpURLConnection로 연결을 합니다.

Page 71: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

BufferedInputStream으로 데이터를 저장합니다. (Reader가 아닙니다!)

Page 72: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

FileOutputStream openFileOutput을 사용하고 write()를 해서 파일을 기록합니다.

Page 73: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

외부에서 사용하실때에는 위와 같이 Context로 생성해주고 함수를 호출 해주기만 하면 됩니다.

!!

하지만 이 역시 편하지만 문제가 있는 방식입니다.

좀더 방어적인 코드를 추가하거나 라이브러리를 사용해야 상용화를 할때 안정된 앱을 만들 수 있습니다.

Page 74: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

1)데이터 요청

2)서버로 부터JSON으로 데이터 받음

3)서버로부터 받은 데이터를 전달

4)JSON 데이터를 Dao에 전달

5)JSON 데이터를 파싱하여 SQLite에 insert하기

FileDownloader 클래스를 사용할려면 JSON을 파싱하여 이미지의 주소를 알게되는 Dao에서 사용해 줘야할 것 같습니다.

Page 75: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Dao에서 DB에 데이터를 넣는 함수에 Context를 넣어 FileDownloader를 만들어 줍니다.

Page 76: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

데이터를 다 파싱하였을때 파일도 다운로드하도록 좀 전에 만든

함수를 호출하여줍니다. (파일 경로, 파일명)

자신의 서버 주소에 맞게 수정!

Page 77: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

SERVER

1)데이터 요청

2)서버로 부터JSON으로 데이터 받음

3)서버로부터 받은 데이터를 전달

4)JSON 데이터를 Dao에 전달

5)JSON 데이터를 파싱하여 SQLite에 insert하기

이미지 파일 다운 받음

지금까지의 진행 사항

Page 78: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

서버로부터 데이터를 받는 부분을 고치는 것은 거의 다 끝나가지만 아직 고치지 않은 곳이 있습니다.

Page 79: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

CustomAdapter의 ImageView의 부분으로 지금은 Asset에 있는 이미지를 가져와 리스트에 표시를 하고 있습니다.

!이 부분을 FileDownloader로 다운받은 이미지를 가져와서

ImageView에 표시하도록 해야합니다.

Page 80: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

FileDownloader에서 한것처럼 FileDir을 가져온 후 BitmapFactory로 Bitmap으로 만들어 ImageView에 넣어 줍니다.

Page 81: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

데이터가 잘 표시되고 있습니다^^

Page 82: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

마찬가지로 ArticleViewer Activity에도 Asset이 아니라 File로 사진을 가져오게 합니다.

Page 83: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

CustomAdapter Class에서 하였던것과 동일하게 article로부터 getImgName()으로 파일명을 받아와

Bitmap으로 ImageView에 표시를 합니다.

Page 84: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

과제가 아닙니다!!생각해 봅시다.(Advanced를 위한)

안드로이드에서 개발자를 가장 괴롭히는 것중 하나가 OutOfMemory입니다…(특히 이미지를 불러올때!)

!디바이스 자체 메모리도 적은데다가

실제로 앱에서 그 용량을 전부 다 쓸 수 없기 때문입니다. (dalvik VM이 프로세스마다 다른 메모리를 할당해 줍니다.)

!메모리를 회수하기 위해 recycle()을 잘 사용하고

!처음 이미지를 불러올때에도

리사이징해서 필요한 만큼만 불러오는 방법등 !

여러가지 방법들을 조사해서 적용시켜 보시길 바랍니다…

http://helloworld.naver.com/helloworld/539525Android 앱 메모리 최적화 - NHN 개발자 블로그

Page 85: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

게시글 업로드 하기

Page 86: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

ArticleWrite1)글 입력 창으로 이동

Page 87: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

ArticleWrite1)글 입력 창으로 이동 2)글 제목,내용, 사진 경로등을 전달

Page 88: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

ArticleWrite1)글 입력 창으로 이동 2)글 제목,내용, 사진 경로등을 전달

3)post방식으로 서버에 사진 전송

Page 89: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

쓰기 버튼을 누르면 글 쓰기용 액티비트로 이동

Page 90: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

디바이스 내에 있는 사진 파일 가져오기

Page 91: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Intent startActivityForResult

Page 92: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

단순히 화면 전환을 위해 사용하던 Intent를 데이터를 요청하고 그 결과를 받아오는 용도로 사용합니다.

Page 93: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

[Android] startActivityForResult(), onActivityResult() 사용하기 http://blog.naver.com/hisukdory/50088038280

Page 94: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

쓰기 버튼EditText

EditText

EditText

ImageButton

누르면 글이 업로드

누르면 사진 선택

ArticleWriter 레이아웃 구성

Page 95: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

ArticleWriter Activity를 생성한 다음 레이아웃의 위젯들의 Id를 다 찾아주세요…

(마지막 노가다…)

Page 96: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

MainActivity에 인텐트를 걸어주세요^^; refresh버튼에는 refreshData()를 호출하도록 하였습니다.

Page 97: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

버튼에 OnClickListener를 달아 주세요

Page 98: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

사진 선택 버튼에 Intent에 Activity Class가 아닌 Intent.ACTION_PICK와 setType()으로 Images.Media.CONTENT_TYPE 타입과 setData()Images.Media.EXTERNAL_CONTENT_URI

데이터를 넣어 주세요

Page 99: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

매번 하던 startActivity()가 아니라 startActivityForResult()로 Intent를 요청해 주세요 2번째 인자는 요청에 대한 내용을 구분하기 위한

int값인데 구분하기 쉽도록 REQUEST_PHOTO_ALBUM으로 변수를 하나 만들어 사용하였습니다.

Page 100: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

[Android] startActivityForResult(), onActivityResult() 사용하기 http://blog.naver.com/hisukdory/50088038280

결과(데이터)를 받아오는 함수 작성하기

Page 101: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

startActivityForResult()로 호출한 결과는 onActivityResult()로 돌아옵니다.

Page 102: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

startActivityForResult()에 두번째 인자로 requestCode로 어떤 요청으로부터 돌아온 결과인지를 if문으로 구분 합니다.

Page 103: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

안드로이드에는 여러 앱들이 서로 데이터를 주고 받기 위하여 Content Provider를 사용합니다.

!이 Content Provider는 content://~~로 시작하는

CONTENT_URI를 사용합니다. (ex. content://media/external/images/media/317930)

!문제는 이것이 실제 파일의 주소가 아니라 Content Provider를 통해야 하는 주소여서

!파일을 업로드 하기 위해서는 실제 주소가 필요합니다.

!실제 주소를 얻는 함수는 아래의 주소에서 복사해주시길 바랍니다.

http://pastebin.com/7iJxYXYNAndroid Basic시간에!

Page 104: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

실제 주소를 가져오는 함수를 넣었습니다…

Page 105: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Result에 돌아오는 Intent data로부터 getData()를 한 후 getRealPathUri()함수를 이용하여 실제 Uri를 받아왔습니다.

!String 변수에 실제 경로와 파일명을 저장하였습니다.

Page 106: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

CustomAdapter에서 한 것처럼 사진 파일을 Bitmap으로 바꾸어 이미지를 표시합니다.

Page 107: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

킷캣부터 Manifest 권한 관리가 더 엄격해졌습니다. AndroidManifest.xml파일에

전에 인터넷 권한을 주었던 것처럼 !

<uses-permission android:name=“android.permission.READ_EXTERNAL_STORAGE"/> 외부파일 읽기 권한을 주세요…

Page 108: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

사진 추가 버튼을 누르고 앨범에서 사진을 선택을 하면 이미지 버튼에 선택한 사진이 잘 표시 됩니다^^

Page 109: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

사용자가 사진을 선택하다 도중에 취소를 하면 null값이 리턴될 수 있습니다.

!이를 회피하기 위해 try catch로 잘 회피합시다…

Page 110: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

너무 큰 사진파일을 넣으면 OutOfMemory가 발생하여 앱이 종료 될 수 있습니다.

!

가능하면 아래의 샘플이미지 생성 앱을 사용하여 작은 사진파일을 업로드해 주세요

(이미지 최적화, 메모리 관리가 필요합니다.)

http://ui.nhnnext.org/crong/scope/android/week4/TestPhotoCopier.apk

Page 111: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

다운 받으신 apk파일을 제니모션 안으로 넣어주세요

Page 112: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

COPY! 버튼을 누르면

!샘플로 사용될

이미지들이 복사됩니다.

Page 113: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

갤러리에 보시면 NEXTAGRAM이라는 폴더에 복사된 사진이 표시됩니다.

!혹 사진이 보이지 않으면 미디어 스캔을 해주시거나 단말기를 재시작해주세요

Page 114: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

ArticleWrite1)글 입력 창으로 이동 2)글 제목,내용, 사진 경로등을 전달

이때까지 글쓰기 내용을 입력하는 부분을 하였고 이제 업로드 하는 클래스를 만들어 보겠습니다.

Page 115: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

업로드를 담당하는 ProxyUP 클래스를 만들어 보겠습니다.

Page 116: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

기본적인 구조는 기존의 Proxy와 동일하지만 HttpURLConnection에서의 Post방식의 업로드는

네트워크의 선행이 갖추어지지 않으면 상당히 어려운 부분이 많습니다…

!

따라서 이번 예제에서는 샘플코드를 제공하고 설명만 하도록 하겠습니다.

!

혹 직접 구현하고 싶으신 분은 이 방법이나 다른 방법을 이용하시길 바랍니다.

(Apache HttpComponents 등등…)

http://pastebin.com/EWUwmThC

Page 117: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

복붙의 결과로 다음과 같은 긴 클래스가 생겼습니다… !

패키지명과 서버주소를 자신에게 맞추어서 수정해주세요

Page 118: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

여기서 사용할 함수인 uploadArticle은 게시글 정보를 담고있는 Article하고 사진이 있는 파일 경로를 받습니다.

!기본적인 내용은 Proxy때와 같지만 Content-Type 부분이 달라졌습니다.

Page 119: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

어디서 많이 보던 내용…https://leansys.com/download/networks/lec11.pdf네트워크 11주차 김종규

Page 120: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

미리보는 패킷 분석 내용… (By Wireshark)

구분자

Page 121: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이 부분은 Stream으로 데이터를 쓰는 부분으로 게시글의 내용을 업로드하고 있습니다.

Page 122: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

KEY

VALUE

getPostData함수는 POST형식에 맞게 데이터를 가공해줍니다.

Page 123: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이 부분은 POST방식으로 파일을 업로드 하는 부분입니다. 먼저 Content name 을 uploadedfile로 하고 FileInputStream으로

파일을 읽어들이면서 서버에 업로드를 하고 있습니다.

Page 124: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

post방식으로 각 이름별로 데이터를받아서 변수에 담기

uploadedfile이라는 이름의 파일 데이터를 받기

서버의 upload.php파일을 다시 보면 앞에서 사용한 이름으로 데이터를 구분해서 처리하고 있습니다.

Page 125: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

나머지 부분은 Proxy와 마찬가지로 서버의 데이터를 받아와 String형태로 리턴해줍니다.

(이 예제에서는 이 데이터에 대한 예외처리는 하지 않습니다.)

Page 126: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

ArticleWrite1)글 입력 창으로 이동 2)글 제목,내용, 사진 경로등을 전달

3)post방식으로 서버에 사진 전송

포스트 방식으로 업로드하는 함수는 구현이 되어있고…

Page 127: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

ArticleWriter1)글 입력 창으로 이동 2)글 제목,내용, 사진 경로등을 전달

ArticleWriter Activity에서 ProxyUP으로 데이터를 보내주는 부분을 마저 구현해보겠습니다.

Page 128: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

다시 ArticleWriter Activity로 돌아와 Write버튼에 마저 이벤트를 달아줍니다.

Page 129: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

네트워크 작업이므로 스레드를 만들어주고…

Page 130: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Article클래스로 게시글 정보를 만들어줍니다.

Page 131: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

사실 ID는 이 클라이언트가 ID, PASS기반 인증을 안해서 안드로이드 디바이스의 고유번호인 ANDROID_ID를

이용하여 고유값을 ID로 사용합니다. !

DATE는 SimpleDateFormat을 이용하여 ‘년월일 시분’단위로 표시합니다.

Page 132: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이제 ProxyUP클래스에 article과 사진의 경로를 보내주면 업로드가 진행됩니다.

Page 133: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

과제가 아닙니다!!생각해 봅시다.(Advanced를 위한)

파일명을 아무런 변경없이 그대로 서버에 올라가 전송이 되고 있습니다.

!만약 같은 파일명의 다른 사진이 서버에 올라가면 어떻게 될까요? 타임이나 각종 여러 값을 이용해서 간단하게 파일명을 만들어주는

함수를 하나 만들어봐보세요 !!

ID로 사용한 ANDROID_ID는 개인정보에 해당하는 정보입니다.

수집시의 법적인 동의 요구절차는 둘째치고 노출되어서 좋을것은 없는 정보입니다.

!항상 같은 값만 가지면 되므로

ID를 암호화를 하는 함수를 하나 만들어봐보세요

Page 134: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

글쓰기 버튼을 누르고…

Page 135: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

어라? 반응이 없네

업로드가 된건가?

Page 136: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

메인으로 돌아가서 새로고침을 누르니까

업로드 되었던 내용이 나오네…

Page 137: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

불편한 경우가 몇개 있는데 개선한 방법은 없을까?

Page 138: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

게시글이 업로드 중임을 알려주자!

Page 139: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 140: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 141: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 142: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 143: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 144: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 145: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 146: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

강의자료 로딩중

Page 147: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

ProgressDialog를 만들어 봅시다!

Page 148: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

ArticleWriter Activity에 ProgressDialog를 만들어줍니다.

Page 149: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

스레드 안에서 UI를 제어해야 하므로 Handler를 만들어서 사용합니다.

Page 150: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

ProgressDialog.show(Context, “Title”, “Message”)를 이용해 진행창을 표시합니다.

Page 151: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

작업이 끝난 부분에도 Handler를 만들고 그 안에 cancel()을 사용 해 ProgressDialog를 닫고

!더 이상 ArticleWriter Activity에서 할 일이 없으므로

finish()를 사용하여 Activity를 종료합니다.

Page 152: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

ProgressDialog 닫기

시간이 걸리는 작업 실행

ProgressDialog 실행

Page 153: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

업로드중입니다.

Page 154: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이번엔 새로고침 버튼을 안눌러도 새로고침이 되도록 합니다.

Page 155: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

http://developer.android.com/training/basics/activity-lifecycle/starting.htmlManaging the Activity Lifecycle

안드로이드에는 생명주기라는 것이 있습니다.

Page 156: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

http://developer.android.com/training/basics/activity-lifecycle/starting.htmlManaging the Activity Lifecycle

이때까지 주로 이 Create단에서 작업을 해왔습니다. 이 부분은 Activity가 생성될때 한번만 실행됩니다.

Page 157: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

http://developer.android.com/training/basics/activity-lifecycle/starting.htmlManaging the Activity Lifecycle

하지만 Resume에서 작업을 하게 되면 Pause가 되었던 Stop이 되었던

Activity가 다시 실행할때 호출이 됩니다.

Page 158: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

http://developer.android.com/training/basics/activity-lifecycle/starting.htmlManaging the Activity Lifecycle

이 Resume부분에 새로고침 함수를 넣어서 Activity가 다시 보여질때마다 새로고침이 되도록 해봅니다.

!자세한 내용은 Android Basic에서!

Page 159: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main Activity를 보면 onCreate()가 있고 그 안에 새로고침이 있습니다.

Page 160: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

onResume()을 만들고 onCreate()에 있던 내용을 옮겨 넣습니다.

Page 161: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

http://developer.android.com/training/basics/activity-lifecycle/starting.htmlManaging the Activity Lifecycle

이렇게 되면 Activity가 Stop이 되었거나 Pause상황이 되었을때

(다른 앱에서 finish()로 넘어오거나 디바이스 화면 전원을 껏다 켰을때) 다시 onResume()이 호출되고 리스트 새로고침을 합니다.

Page 162: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

NEXTAGTAM 완성!

Page 163: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

하지만 완성도를 높이기 위한 수정은 필수!

Page 164: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Advanced를 목표로 하시는 분은 레이아웃이나 글자 크기등등 UI보다는

!

생각해보기의 내용들을 한번 해결을 해보시면 좋을것같습니다

Page 165: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

그래도 시간이 남으신다면…

Page 166: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

아래의 링크 자료를 참고하셔서 액션바나 사이드 네비게이션을 구현해보세요!

액션바 사이드 네비게이션

Page 167: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

정리하기

Page 168: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

Main

Proxy

Dao

ProxyUP

SERVER

7)Dao로 부터 가져온 데이터를 리스트에 표시

ArticleWrite8)글 입력 창으로 이동 9)글 제목,내용, 사진 경로등을 전달

10)post방식으로 서버에 사진 전송

이때까지 서버

Proxy

Dao

ProxyUP

SERVER

1)데이터 요청

2)서버로 부터JSON으로 데이터 받음

3)서버로부터 받은 데이터를 전달

4)JSON 데이터를 Dao에 전달

5)JSON 데이터를 파싱하여 SQLite에 insert하기

6)Dao에 저장되어 있는 게시글 데이터를 가져오기

이때까지 안드로이드로 서버와 데이터를 주고 받고 DB에 데이터를 저장하여 원하는 형태로 보여주는

시중의 많은 앱들과 비슷한 형태를 구현을 해보았습니다.

Page 169: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

이 개발경험 프로젝트에서의 예제는 자주 사용되는 여러가지 요소를 경험을 해보기 위해

깊게 나가지 못한 부분이 있습니다. !

이런 부분은 Android수업시간에서 좀더 깊게 배우시면 될 것 같습니다^^;

Page 170: [NEXT] Android 개발 경험 프로젝트 4일차 (Networking)

수고하셨습니다^^