본문 바로가기
활동/우아한테크캠프5기

우아한 테크캠프 2주차 - 2

by ESHC 2022. 7. 18.

 

2주차는 팀 프로젝트로 진행되었고 3주차까지 동일한 프로젝트를 진행하게 된다. 협업 프로젝트 과정에서 배운 부분과 수업을 통해 학습한 내용을 정리했다.

*정리할 내용이 생각보다 많아서 글을 나눠서 정리하였습니다.

 


 

URLConnection, HttpURLConnection

HTTP 프로토콜은 요청 URI와 본문에 해당하는 엔티티이외에 요청과 응답에 대해 추가적인 정보를 헤더로 제공해 주어야 한다. 이 때 URLConnection 클래스나 HttpURLConnection 클래스를 통해 요청 메시지를 작성하고 응답 메시지를 해석할 수 있다. URLConnection 클래스는 java.net에서 제공하는 클래스이며 HttpURLConnection 클래스의 상위 클래스이다. URLConnection 클래스를 사용하는 방법은 아래와 같다. (자바에서 사용되는 Method 형태 기준)

1. URL 객체 생성

URL클래스를 통해 생성할 수 있다.

2. URL 객체로부터 URLConnection 객체 생성

URLConnection 객체는 URL클래스의 openConnection() 메소드를 통해 생성할 수 있다.

3. setRequestProperty() or addRequestProperty() 메소드를 사용하여 HTTP 헤더 작성

4. setConnectTimeout() 메소드로 타임 아웃 시간을 설정

5. URLConnection 클래스가 제공하는 setDoOutput() 메소드와 setDoInput() 메소드를 사용하여 메시지 내 엔티티의 입력 또는 출력 여부를 결정

6. HTTP 메시지 내 엔티티를 만들어야 한다면 OutputStream 객체를 사용하여 제작

7. connect() 메소드를 사용하여 서버와 접속(선택사항)

connect() 메소드를 사용하지 않더라도 getInputStream() 메소드 또는 getContentType() 메소드를 호출하면 메소드 내부에서 connect() 메소드가 자동으로 실행된다.

8. 서버로부터 받은 응답 메시지로부터 필요한 데이터를 추출

InputStreamReader 객체를 사용하여 InputStream객체로부터 데이터를 읽을 수 있다.

9. 작업이 완료되었으면 close() 메소드를 사용하여 URLConnection 객체를 닫고 모든 리소스를 해제

 

하위 클래스인 HttpURLConnection클래스를 사용하면 웹 서버에 접속할 때 더 수월하다.

setRequestMethod()를 통해 HTTP 프로토콜에 들어가는 요청 메소드를 결정할 수 있다.getResponseCode()를 통해 HTTP 응답 메시지의 상태 코드를 정수값으로 얻을 수 있고, getResponseMessage()를 통해 HTTP 응답 메시지 내 상태 라인에 포함되어 있는 '이유 문구'를 얻을 수 있다.dissconnect()를 통해 Connection 헤더를 사용하여 연결된 서버와의 세션을 종료시킬 수 있다.

 

참고 : 기적을 부르는 안드로이드 통신 프로그래밍 제 3판(박헌재, 투에이치앤에스)

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9791195570546&orderClick=LAG&Kc= 

 

안드로이드 통신 프로그래밍 - 교보문고

‘기적을 부르는 안드로이드 통신 프로그래밍’은 다음과 같은 특징을 갖고 있습니다.① 초보자들도 이해하는데 무리가 없도록 쉽게 쓰여졌습니다.② 통신의 기초부터 고급 통신 기술까지 폭

www.kyobobook.co.kr

 

Thread, Looper, MessageQueue, Message, Handler, Runnable, HandlerThread

Thread

안드로이드에서는 UI를 업데이트하기 위해 단일 스레드 모델이 적용된다. 메인 스레드라고 불리우는 스레드만이 UI 업데이트를 허용하기 때문에 메인 스레드를  UI스레드라고도 불리우고, 컴포넌트의 생명주기 메서드와 그 안의 메서드 호출도 기본적으로 메인 스레드에서 실행된다. 

 

Looper

일단 Looper는 스레드별로 생성이 되어진다. 메인 스레드의 메인 Looper는 Looper.prepareMainLooper()를 호출하여 생성하는데 Looper.getMainLooper()를 사용하여 메인 Looper를 가져올 수 있다. Looper는 각각의 MessageQueue를 가지는데 Looper안에는 무한 반복문이 돌고 있고 MessageQueue에서 Message를 꺼내서 처리하는 작업을 한다. 

 

MessageQueue

MessageQueue는 Message를 담는 자료구조인데 Message는 실행 타임스탬프순으로 삽입되고 링크로 연결되어, 실행 시간이 빠른 것부터 순차적으로 꺼내어진다.

 

Message

데이터를 전송하거나 작업을 요청하기 위한 객체로, 데이터와 Runnable 객체를 제공한다. Message.obtain()로 Message를 생성할 수 있다.

 

Handler

Handler는 Message를 MessageQueue에 넣는 기능과 MessageQueue에서 꺼내어서 처리하는 기능을 함께 제공한다. Handler를 할 때 두 개의 파라미터를 넣을 수 있는데 Looper와 Handler.Callback이 전달될 수 있다. Looper를 따로 파라미터로 지정하지 않는다면 생성자를 호출하는 스레드의 Looper를 사용하겠다는 의미이다. 백그라운드 스레드에서 Handler 생성자를 사용할 때 유의해야 하는데 따로 Looper가 준비되어 있지 않으면 에러가 발생하기 때문이다. Handler에서 Message를 보내는 메서드는 크게 send-()와 post-()로 볼 수 있는데 -post에는 Runnable객체가 포함된다. 

 

Runnable

Runnable객체는 간단하게 실행할 코드가 담긴 객체이다. Runnable 인터페이스는 단 하나의 메서드, run() 메서드만 가지는데 실행할 코드를 run() 오버라이드하여 작성하면 된다.

 

HandlerThread

HandlerThread는 Looper를 가진 스레드이면서 Handler에서 사용하기 위한 스레드라고 볼 수 있다. 스레드에서 Looper를 시작하고 스레드 외부에서 Handler를 생성하는 방식으로 Handler를 Looper에 연결한다. 연결된 Handler에서 보낸 Message가 HandlerThread에서 생성한 스레드에서 처리된다. HandlerThread는 단일 스레드에서 순차적인 작업이 필요할 때 사용될  수 있다.

 

백그라운드 스레드와 메인 스레드 사이의 통신이 필요할 때 Handler를 통해 Message를 전달하여 통신을 할 수 있다.

 

참고 : https://bubble-dev.tistory.com/entry/안드로이드-Looper-Message-Queue?category=1112715

https://m.blog.naver.com/horajjan/220963041580

https://recipes4dev.tistory.com/166

책 - 안드로이드 프로그래밍 Next Step(노재춘, 프로그래밍인사이트)

http://www.kyobobook.co.kr/product/detailViewKor.laf?ejkGb=KOR&mallGb=KOR&barcode=9788966263073&orderClick=LEA&Kc= 

 

안드로이드 프로그래밍 Next Step - 교보문고

제대로 된 앱을 만드는 컴포넌트 활용 노하우 | 대상독자- 앱을 개발하면서 자신이 정말 제대로 만들고 있는지, 문제를 올바르게 해결하고 있는지 의문을 갖는 분- 안드로이드 컴포넌트를 어떤

www.kyobobook.co.kr

 

코루틴

코루틴은 비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 동시 실행 설계 패턴이다. 

스레드를 사용하여 비동기 처리가 가능하지만 blocking되어 자원이 낭비되는 경우가 발생할 수도 있다. 코루틴도 스레드를 사용하지만 스레드 안의 여러 코루틴이 작업 단위 형태로 포함되어 작업을 처리할 수 있다. 다른 스레드에서의 결과가 필요한 코루틴 작업이 있을 경우 그 코루틴 작업과 동일한 스레드에 다른 코루틴이 다른 스레드의 결과가 나올 때까지 작업을 처리할 수 있고 다른 스레드의 결과가 나오면 다시 원래의 코루틴 작업을 재개할 수 있다. 스레드를 효율적으로 사용할 수 있다는 말로 볼 수 있다.

 

Dispatcher

디스패처를 통해 코루틴이 어떤 스레드에서 작업을 처리할 지 정할 수 있다. 안드로이드에서는 Main, IO, Default, Unconfined가 있다.

Main : UI 작업을 위한 Main Thread에서 처리를 위해

Default : Main Thread가 아닌 Thread에서 CPU 작업을 하기 위해

Unconfined : 특정 Thread가 정해지지 않고 호출한 Thread에서 처리, 특정 Thread에 국한된 작업이 아닌 경우 적절

IO : 파일 읽기나 네트워크 IO 작업을 실행하는데 최적화

 

launch, async

결과 반환이 필요 없을 때는 launch를 사용할 수 있고 결과 반환이 필요할 때는 async를 사용할 수 있는데 await와 같이 사용해준다.

 

withContext

withContext를 통해 비동기 작업을 순차 코드처럼 작성할 수 있게 되는데 withContext 블록의 마지막 줄의 값이 반환 값이 되고 withContext가 끝나기 전까지 해당 코루틴은 일시정지가 된다는 점을 이용할 수 있다. 

 

 

참고 : https://developer.android.com/kotlin/coroutines

https://kotlinworld.com/139?category=973476 

 

댓글