Concepts of Network Programming
1. Network Programming
<uses-permission android:name="android.permission.INTERNET"/>
2. HTTP 통신
1) HttpURLConnection
- java SE에서 제공되는 API
- 표준 라이브러리, 초기 버전부터 제공
- 코드가 길고 복잡해짐
- 대부분 HttpURLConnection를 직접 사용하기 보다는 이를 추상화시킨 라이브러리를 이용
2) HttpClient
- apache http 라이브러리
- 안드로이드 초기 HttpURLConnection에 내부적인 문제가 있었음
- 따라서 HttpClient도 표준 라이브러리에 포함되어 있었음
- Android 6.0에서는 Apache HTTP 클라이언트에 대한 지원이 제거
- HttpURLConnection의 내부적인 문제 해결
- http 네트워킹을 위한 많은 라이브러리들이 나옴
- Android 9부터는 이 라이브러리가 bootclasspath에서 제거되고 기본적으로 앱에서 사용할 수 없음
- Android 9이상을 대상으로 하는 앱이 Apache HTTP 클라이언트를 계속 사용하려면 AndroidManifest.xml에 추가해야 함
3) volley
- 2013년 Google I/O에서 발표한 라이브러리
- http 통신을 위한 다양한 기능을 제공해주는 라이브러리
- 추상화 클래스 레벨을 높여 중복되는 코드 없이 간결하게 작성 가능
- 1.0.0 버전에서는 내부적으로 apache http 라이브러리를 이용했으며 1.1.1 버전에서는 apache http 종속성이 제거
- 구글의 api이지만 별도의 라이브러리이므로 dependency 관계를 설정해야 함
4) okHttp
5) retrofit
- 현시점 안드로이드 개발자 사이에 가장 이용 비율이 높고 유명한 라이브러리
- 2013년 1.0이 발표되었고 2016년 2.0이 발표
- square라는 회사에서 만들어 내부적으로 okHttp를 이용
3. HTTP 통신을 위한 보안 정책 확인
- API level 28부터 네트워크 보안 정책 변경 - http 프로토콜이 금지
- https는 문제 없으며 http인 경우 설정이 필요
1) AndroidManifest.xml에서 usesCleartextTraffic 설정
<application
android:usesCleartextTraffic="true">
- API level 28부터 기본값이 false로 설정되어 있어 명시적으로 true로 설정해주어야 함
2) network_security_config 이용
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.1.2</domain>
</domain-config>
</network-security-config>
<application
android:networkSecurityConfig="@xml/network_security_config">
- 임의의 xml 파일에 루트 태그로 network-security-config 설정
- 내부의 domain 태그에 http 통신을 허용할 도메인이나 ip 주소를 등록
- 1은 모든 http 통신을 허용하고 2는 설정한 것만 http 통신을 허용한다는 차이점이 있음
Network 정보 확인
- 서버와 네트워크 작업을 하기 전, 디바이스의 네트워크 상태를 파악(연결여부, 와이파이/이동통신사망 확인)
1. ConnectivityManager
1) ConnectivityManager를 이용해 네트워크 상태를 파악
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
2) Network 객체(네트워크 정보가 담기는 객체) 획득
val nw = connectivityManager.activeNetwork
val actNw = connectivityManager.getNetworkCapabilities(nw)
- ConnectivityManager의 getActiveNetwork()을 이용해 Network 객체 획득
- Network 객체를 getNetworkCapabilities() 함수의 매개변수로 지정하면 현재 접속된 네트워크망 정보를 획득 가능
3) 접속 상태 확인
actNw.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) -> {
return "wifi online"
}
actNw.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) -> {
return "cellular available"
}
- hasTransport() 함수를 이용해 현재 폰이 와이파이에 접속된 상태인지 이동통신사망에 접속된 상태인지 파악
- 만약 와이파이와 이동통신사망 둘 다에 접속된 상태가 아니라면 현재 네트워킹이 안되는 상태임