태터데스크 관리자

도움말
닫기
적용하기   첫페이지 만들기

태터데스크 메시지

저장하였습니다.
2019.04.09 11:30


[android] CONNECTIVITY_ACTION deprecated 에 대한 이야기


https://developer.android.com/reference/android/net/ConnectivityManager.html?hl=ko#CONNECTIVITY_ACTION

added api level, background restriction, CHANGE_NETWORK_STATE, Connectivity, ConnectivityManager, ConnectivityManager.CONNECTIVITY_ACTION, ConnectivityThread, connectivity_action deprecated, default network, deprecated, deprecated broadcast, dynamic receiver, Example, EXTRA_NETWORK, EXTRA_NETWORK_REQUEST, handler thread, networkcallback, networkcapabilities, networkrequest, NET_CAPABILITY_CAPTIVE_PORTAL, NET_CAPABILITY_VALIDATED, NOS, onAvailable, onLost, oos, PendingIntent, permission, pos, registerDefaultNetworkCallback, registerdefaultnetworkcallback example, registernetworkcallback, registernetworkcallback example, releaseNetwork, requestNetwork, Settings.System.canwrite, static receiver, targetsdk, targetsdk 24, unregisterNetworkCallback, [android] CONNECTIVITY_ACTION deprecated 에 대한 이야기, 테스트를 통한 동작 확인


-

Connectivity 가 변경되었을 때 받을 수 있는 broadcast 는 ConnectivityManager.CONNECTIVITY_ACTION 가 있었다.

그러나 이 녀석은 API 28 (POS) 부터 deprecated 되었다.



-

사실 이 녀석은 이미 deprecated 의 징조를 띄고 있었다.

targetSdk 24 (NOS) 부터 static receiver 로 받을 수 없게 되었고,

targetSdk 26 (OOS) 부터는 background restriction 정책으로 이 녀석을 포함한 다른 녀석들도 static receiver 로 받을 수 없게 되었다.

그리고 결국 API 28 (POS) 부터는 deprecated 된 것이다.


deprecated 가 되었기 때문에 사실 targetSdk 28 (POS) 부터는 못 받아도 할 말이 없는 녀석이긴 한데..

QOS 부터는 이 녀석들이 targetSdk 상관없이 iOS 처럼 동작을 확 변경하는 태세전환을 보여서 미리 대비하는 것이 좋아보인다.



-

ConnectivityManager.CONNECTIVITY_ACTION broadcast 을 대신해 사용할 수 있는 API 는 다음과 같다.

requestNetwork(NetworkRequest, PendingInent)

registerNetworkCallback(NetworkRequest, PendingIntent)

registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback)


위 API 들을 통해서 더 빠르게, 관심있는 network 에 대한 더 디테일한 정보를 받을 수 있다.





ConnectivityManager.requestNetwork(NetworkRequest, PendingIntent) - Link


-

API 22(LOS MR1) 에 소개된 API 이다.

NetworkCapabilities 를 충족하는 network 를 요청한다.

이 녀석은 networkCallback 을 전달하는 API 와 동일한데, 대신 PendingIntent 를 사용하기 때문에 life time 이 더 길다고 볼 수 있다.



-

PendingIntent 는 broadcast intent 이다.

여기는 두개의 extra 가 들어가는데, EXTRA_NETWORK 에 Network 객체가, 그리고 EXTRA_NETWORK_REQUEST 에 NetworkRequest 객체(요청한 녀석과 동일)가 들어있다. 



-

동일한 NetworkRequest 가 등록되면, 기존것을 대체한다.



-

releaseNetwork(PendingIntent) 를 통해 request 가 release 될 수 있다.



-

NetworkCapabilities.NET_CAPABILITY_VALIDATED 나 NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL 에 대한 network request 는 현재 지원되지 않는다.

이 capabilities 는 특정 network 에서 절대 발생하지 않고, network 에서 미리 알 수 없는 상태이기 때문이다.


이 함수는 caller 가 Manifest.permission.CHANGE_NETWORK_STATE permission 을 갖거나, Settings.System.canWrite(Context) 에 정의한 setting 값 변화 permission 을 갖기를 요구한다.






registerNetworkCallback(NetworkRequest, ConnectivityManager.NetworkCallback) - Link


-

API 21 (LOS) 에 소개된 API 다.

주어진 NetworkRequest 조건에 맞는 network 에 대한 notification 을 받도록 callback 을 등록하는 함수이다.

unregisterNetworkCallback(NetworkCallback) 이 불리기 전까지 계속 불린다.

Manifest.permission.ACCESS_NETWORK_STATE 의 권한이 요구된다.





registerDefaultNetworkCallback(ConnectivityManager.NetworkCallback) - Link


-

API 24 (NOS) 에 소개된 API 이다.

이는 System default network 에 대한 change 를 notification 으로 받는다.

unregisterNetworkCallback(NetworkCallback) 이 불릴때까지 계속 불린다.

Manifest.permission.ACCESS_NETWORK_STATE 권한이 요구된다.





API 살펴봤으니 NetworkCallback 에 대해서도 알아본다. - Link

public static class NetworkCallback {
    // hide 된 몇몇 함수들도 있다.
    public void onAvailable(Network network) {}
    public void onLosing(Network network, int maxMsToLive) {}
    public void onLost(Network network) {}
    public void onUnavailable() {}
    public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {}
    public void onLinkPropertiesChanged(Network network, LinkProperties linkProperties) {}
}




테스트를 통한 동작 확인


registerNetworkCallback Test


-

WIFI 가 연결되어 있는 상태에서 다음과 같이 callback 을 등록하면..

val cm = getSystemService(ConnectivityManager::class.java)
val wifiNetworkRequest = NetworkRequest.Builder()
        .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
        .build()
val callback = object : ConnectivityManager.NetworkCallback() {
    override fun onAvailable(network: Network) {
        Log.e("cklee", "MMMM network : $network")
    }

    override fun onLost(network: Network?) {
        Log.e("cklee", "MMMM lost network : $network")
    }
}
cm.registerNetworkCallback(wifiNetworkRequest, callback)

와이파이가 연결되어 있는 상태 -> register -> 바로 onAvailable callback 이 한번 불림.

이 상태에서 와이파이 연결을 해제 -> 바로 onLost 함수가 불림.


와이파이가 연결되어 있지 않은 상태 -> register -> onLost 가 불리지는 않음.

함수명에 맞게 잘 동작한다. onLost 는 실제 연결이 끊어졌을때만 불린다. ( Available 은 가능성을 보는 것이기 때문에 바로 불리는 것이 reasonable 하다.)

이 상태에서 와이파이 연결 -> 바로 onAvailable 함수 불림.



-

Network 객체의 toString 은 hashCode 를 print 하도록 되어 있음.

매 onAvailable 시마다 hash 값이 달라지므로 다른 Network 객체가 생성되어 들어온다고 볼 수 있다.






registerDefaultNetworkCallback Test


-

위와 같은 방식으로 테스트하는데, 등록 API 만 registerDefaultNetworkCallback 로 바꾼다.

default 의 의미를 이해하기 위해 Wifi 와 data 를 껐다 켰다를 반복해보았다.



-

두 network 모두 붙여놓은 상태 -> register -> onAvailable callback 이 1회 불림.

이 상태에서 data off -> onLost 불리지 않음. 메인(default)가 network 가 Wifi 이기 때문인 듯 하다.

이 상태에서 wifi off -> onLost 가 불린다.  ( onAvailable 당시 hash 값과 동일한 녀석이 lost 된다. )



-

register 상태 & 두 network 모두 off 상태 -> wifi on -> onAvailable callback 불림

이 상태에서 data on -> onAvailable 불리지 않음. 

역시나 메인(default) network 는 wifi 이기 때문이라고 이해하면 이해가 된다.



-

wifi 가 우선순위를 갖고 메인(default) network 가 되기 때문에 data 를 위주로 추가 테스트 해보았다.

register & 두 network 모두 on -> wifi off -> onAvailable 불림. 

이 때 hash 는 처음 register 당시의 hash 가 아님, 즉 data network 의 hash 해석되며, data network 가 available 하다고 callback 이 불린 것이다.


이 상태에서 wifi  on -> onAvailable 불림.

data network  가 lost 된 것이 아니라 onLost 는 불리지 않고, default 가 바뀌었기 때문에 wifi 에 대한 onAvailable callback 이 불린다.

이 상태에서 wifi off -> onAvailable 불림.

위의 wifi off 시 onAvailable 에 전달된 hash 와 다른 것으로 보아, onAvailable 이 불릴 때마다 객체 재활용 없이 새로운 녀석이 온다고 보면 될 것 같다.





참고사항이지만 중요한 정보


-

callback 은 ConnectivityThread 라는 HandlerThread 에서 호출된다.






더보기



댓글을 달아 주세요


Posted by 돼지왕왕돼지