네트워크 상태체크하기

enum class NETWORK_STATUS {
    TYPE_WIFI,
    TYPE_MOBILE,
    TYPE_NOT_CONNECTED
}

class NetworkStatus {
    companion object {

        fun getConnectivityStatus(context: Context): NETWORK_STATUS {
            val manager: ConnectivityManager? =
                context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

            if (manager != null) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    val networkCapabilities = manager.getNetworkCapabilities(manager.activeNetwork)

                    if (networkCapabilities != null) {
                        if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
                            return NETWORK_STATUS.TYPE_WIFI
                        } else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
                            return NETWORK_STATUS.TYPE_MOBILE
                        }
                    }
                } else {
                    val networkInfo = manager.activeNetworkInfo

                    if (networkInfo != null) {
                        val type = networkInfo.type

                        if(type == ConnectivityManager.TYPE_WIFI) {
                            return NETWORK_STATUS.TYPE_WIFI
                        } else if (type == ConnectivityManager.TYPE_MOBILE) {
                            return NETWORK_STATUS.TYPE_MOBILE
                        }
                    }
                }
            }

            return NETWORK_STATUS.TYPE_NOT_CONNECTED
        }
    }
}

 

MVP

MVP(Model View Presenter)는 사용자 인터페이스를 구축할 때 이용하는 설계 기법이다.

Model

데이터와 비즈니스 로직이 들어있고, UI에 관한 로직은 가지지 않는다.

데이터베이스나 API 접근에 관한 처리는 여기에 들어간다.

Presenter

모델과 뷰 사이에서 서로 통신한다.

뷰에서 발생한 이벤트가 프레젠터에 알려지면 프레젠터는 그 이벤트에 대응하는 처리.

뷰와 모델 사이에는 항상 프레젠터가 들어간다. 모델이나 뷰의 실체인 인스턴스를 프레젠터로부터 직접 참조하게하지 않고, 인터페이스 등을 이용해 접근할 수 있게 한다.

이렇게 하면 테스트 시에 목 객체(Mock Object)로 대체할 수 있어 테스트하기가 쉬워진다.

MVP 설계의 장점

Model, View, Presenter로 역할을 명확히 나누므로 어느 처리 내용이 어디에 있는지 명확해지고 코드의 관리 효율이 높아진다. MVP패턴으로 설계하면 필연적으로 역할을 나눠야 하기에 액티비티에 구현을 채워넣을 수 없게 된다. 

결과적으로 처리를 나눌 수 있어 액티비티를 작게 만들 수 있다. 또한 뷰와 모델 사이에 프레젠터가 들어가므로 뷰와 모델의 의존관계가 없어진다.

MVP 설계의 단점

프레젠터는 인터페이스를 통해 뷰와 모델에 접근하므로 그것들의 위치를 인터페이스로서 정의할 필요가 있다.

이 부분이 길어지기 쉽다. 또한 모델에서 가져온 데이터를 뷰에 표시하는 것을 개발자가 직접 구현해야 한다.

안드로이드에는 기본적으로 MVP 패턴을 지원하는 프레임워크가 없어서 어떻게 UI 로직을 프레젠터로 분리하는가 하는 설계상의 난도가 높다는 것도 단점으로 들 수 있다.


MVVM

Android Gradle Plugin을 통해 데이터 바인딩(Databinding)이 지원된다.

Databinding은 사용자 인터페이스와 데이터를 연결하는(바인딩하는) 메커니즘이다.

데이터 바인딩을 활용한 설계 기법으로 MVVM(Model View ViewModel)이 있다.

 

모델에는 MVP의 모델처럼 데이터와 비즈니스 로직이 들어간다.

 

뷰는 데이터를 표시한다. MVP와 달리 ViewModel이 모델에서 가져온 데이터를 반영해서 표시한다.

ViewModel 가진 값이 데이터 바인딩으로 자동적으로 뷰에 반영되므로 뷰 부분에서 반영하는 구현을 할 필요가 없어진다. 하지만 안드로이드에서는 애니메이션이나 액티비티 전환 등 ViewModel에서 구현하기 어려운 항목이 있다. 그런 부분은 뷰에서 구현할 필요가 있다.

 

기본적으로 ViewModel은 뷰의 상태와 UI에 관한 로직을 구현하고, 데이터 바인딩을 통해 ViewModel의 상태가 뷰에 반영된다. 또한 뷰 클릭 등의 이벤트를 ViewModel이 받고 모델과 데이터를 주고받아 데이터 바인딩으로 뷰의 상태를 갱신한다.

MVVM 설계의 장점

MVP 패턴처럼 역할을 분리할 수 있으므로 액티비티를 작게 만들 수 있다.

데이터 바인딩으로 MVP일 때 기술하는 모델에서 가져온 데이터를 뷰에 반영하는 로직도 작성할 필요가 없으므로 액티비티의 코드를 많이 줄일 수 있다. 프레젠터와 마찬가지로 뷰에 의존하는 코드가 없어 테스트하기 쉽다.

MVVM 설계의 단점

바인딩에 대한 처리는 자동으로 생성되므로 데이터 바인딩 처리는 블랙박스화돼 있다. 자동으로 생성된 코드는 일반적으로 가독성이 낮고 디버그하기 어렵다.

black은 컴포넌트 안을 보거나 변경할 수 없으므로 고안된 대로 재사용이 가능하다.
고안된 대로 쓸 수 있기 때문에 일관된 프로그래밍이 가능하다.

 

Preference

안드로이드 개발 레벨업 교과서

Activity : 액티비티라는 단어의 의미는 '활동'

사용자가 어떤 활동을 할 때 실행되는 애플리케이션의 컴포넌트를 가리킨다. 액티비티에는 윈도우가 있고, 그 윈도우에 텍스트나 이미지를 표시해 사용자 조작에 반응할 수 있다. UI가 없는 액티비티도 있지만 기본적으로 한 액티비티가 한 화면을 표시한다.

 

AppCompatActivity를 상속하는 Activity를 만들면 Meterial Design의 가이드라인에 따른 AppCompat 라이브러리를 제대로 활용할 수 있다.

AppCompatActivity를 상속할 수 없을 때는 AppCompatDelegate를 이용할 수 있다.

 

Activity의 수명주기

onCreate() 생성 초기화 처리와 뷰 생성(setContentView 호출) 등
onStart() 비표시 통신이나 센서 처리를 시작
onResume() 최전면 표시(맨 앞쪽) 필요한 애니메이션 실행 등의 화면 갱신 처리
onPause() 일부 표시(일시정지) 상태 애니메이션 등 화면 갱신 처리를 정지 또는 일시정지할 때 필요 없는 리소스를 해제하거나 필요한 데이터를 영속화
onStop() 비표시 통신이나 센서 처리를 정지
onDestroy() 폐기 필요 없는 리소스를 해제, 액티비티 참조는 모두 정리
※ Android N부터 멀티윈도우가 도입됐습니다.
   멀티윈도우를 지원하는 경우 애니메이션 실행 등 화면 갱신 처리의 정지는 onStop()에서 한다.

시스템 메모리가 모자랄 경우 시스템은 onStop, onDestroy를 콜백하지 않고 액티비티를 강제 종료시켜 메모리를 확보할 때가 있다. 이런 경우 데이터를 영속적으로 보존하려면 액티비티가 일시정지 상태로 전환되는 onPause에서 이를 처리할 필요가 있다.

 

onCreate와 onDestroy / onStart와 onStop / onResume과 onPause 를 쌍으로 준비와 뒷정리 또는 시작과 종료(취소)하는 조합을 생각하면 어떤 시점에 어떤 작업을 처리할지 상상하기 쉬워진다.

 

onCreate에서 뷰를 만들면 onDestroy에서 해제한다.

뷰는 액티비티가 폐기된 다음, 가비지 콜렉션(GC: Garbage Collection)에 의해 자동으로 메모리에서 해제된다.

 

onStart에서 위치 정보를 취득했다면 onStop에서 취득을 정지하는 식이다.

 

onDestroy에서 액티비티가 폐기되면 GC가 메모리 영역에서 해제한다. 

단, 액티비티의 인스턴스가 다른 클래스에서 참조되고 있을 때는 폐기된 후에도 메모리에 남아 결국 메모리 누수가 발생한다.

 

Activity의 백스택

새로운 액티비티가 시작되면 실행중이던 Activity는 백스택에 들어간다. 또한 시작한 Activity는 태스크라는 그룹에 속한다. 안드로이드 OS의 버전에 따라서도 미묘하게 동작이 달라 다 이해하기는 어려우므로 3가지만 알아두자.

  • 같은 앱에서 시작된 액티비티는 같은 백스택에 쌓인다.
  • taskAffinity의 속성에 따라 소속되는 태스크가 달라진다.
  • launchMode에 따라 Activity 생성의 여부, 새로운 태스크에 속하는 등 Activity의 시작이 달라진다.

백스택에 쌓인 액티비티는 '뒤로가기' 키 등으로 액티비티를 종료하면 차례로 꺼내진다.

 

taskAffinity는 '태스크 친화성' 이라는 의미지만, 대체로 '태스크 이름'으로 바꿔 읽는것이 이해하기 쉽다.

taskAffinity를 지정하지 않은 경우는 자기 앱의 패키지 이름이 태스크 이름이 딘다.

taskAffinity를 설정하지 않으면 그 앱의 taskAffinity는 모두 같아진다.

 

launchMode는 4가지가 있다.  자주 사용하는 것은 standard, singleTop, singleTask의 3가지이다.

standard는 매번 액티비티의 인스턴스를 새로 생성한다.

singleTop은 같은 액티비티가 최상위에서 실행 중이면 액티비티를 생성하지 않고, 그 대신 최상위 인스턴스의 onNewIntent()를 호출한다.

singleTask는 1개의 태스크에 인스턴스가 존재한다. 이미 같은 액티비티가 실행 중이면 액티비티를 생성하지 않는다.


View, Layout

View란 UI를 구성하는 바탕이 되는 컴포넌트로서 네모난 그리기 영역을 가진다.

Layout은 뷰를 어떤 위치에 어떤 크기로 표시할지 결정하는 것입니다.

EditText 속성

 - background 값에 @null을 추가한다.


EditText 활성화, 키패드 보이기, 커서 위치 이동

editText.isFocusableInTouchMode = true
editText.isFocusable = true
editText.selection(editText.length()) // 커서 위치 이동하기

// 키패드 보이기
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.showSoftInput(eidtText, 0)

EditText 비활성화, 키패드 숨기기

editText.isClickable = false
editText.isFocusable = false

// 키패드 숨기기
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(edit_nickname_editmyinfo_a.windowToken, 0)

Reference

 - https://nuggy875.tistory.com/10

 - https://philip1994.tistory.com/12

 - https://programmingsummaries.tistory.com/30

 

+ Recent posts