본문 바로가기

전체 글

(62)
안드로이드 프로젝트의 리뷰어들의 체크리스트 Memory Leaks - context를 유지하는 코드 조각이 있는지? - RxAndroid Code랑 연관이 있따면 RxCall이 생명주기의 끝에 없어지는지? - coroutine을 사용하고 있다면, Jab이 런취되고 viewModel 스코프에 의해 적절히 해방이 되는지? - 만일 CountDownTimer나 AsyncTask를 비디오/오디오 플레이어에서 사용하고 있다면, momory 리소스를 적절히 해방시키는지? - ViewBinding을 사용하고 있다면 onDestroyView에서 null로 셋팅시키는지 Resource Annotations fun showMessage(context: Context, val idRes: Int) { Toast.makeText(context, idRes, Toast..
inline, noinline, crossinline inline 이란? 고차 함수를 사용하면 런타임 패널티가 있기 때문에 함수 구현자체를 코드에 넣음으로써 오버헤드를 없앨 수 있다. >> 고차함수는 객체를 생성하기 때문에 생기는 오버헤드라고 볼 수 있습니다. 인라인은 인스턴스를 만들지 않고 코드를 호출하는 위치에 그대로 복사해서 컴파일되는 바이트코드의 양은 많아지겠지만, 추가적인 객체 생성은 없습니다. inline 함수는 내부적으로 코드를 복사하기 때문에, 인자로 전달 받은 함수는 다른 함수로 전달되거나 참조할 수 없습니다. 그래서 필요한 것이 noinline입니다. noinline 인자 앞에 noinline 키워드를 붙이면 해당 인자는 inline에서 제외됩니다. 따라서 다른 함수의 인자로 전달하는 것이 가능해집니다. crossinline inline ..
Context 클래스 Context 클래스로 가능한 것 - 액티비티 시작 - 브로드캐스트 발생 - 서비스 시작 - 리소스 접근 Context 하위 클래스 Contex 는 추상클래스인데 메서드 구현이 거의 없이 상수 정의와 추상 메서드로 이루어진다. - ContextWrapper (직접 상속) - Activity - Service - Application ContextImpl ContextImpl은 앱에서 싱글톤으로 단 1개의 인스턴스만 갖고 있지 않다! ContextWrapper에 getBaseContext()는 각각 getApplicationContext()라는 2개의 메서드가 별도이다. getBaseContext()는 각각 ContextImpl 인스턴스를 리턴한다. getApplicationContext()는 Applic..
AsyncTask Deprecated 가 되어버렸지만 AsyncTask에 대해서 공부하고 정리하도록 하겠습니다. AsyncTask는 백그라운드 스레드와 UI 스레드에서 작업할 수 있도록 만들어진 것입니다. doInBackground, onPostExecute 두 가지 함수를 이용해서요. AsyncTask는 제네릭 크래스고, Params, Progress, Result 가 있다. AsyncTask 취소 cancel() 메서드가 있다. mCanceld 변수를 true로 만들고, 스레드 작업 이후에 onPostExecute() 대신 onCancelled() 메서드가 불린다. isCancelled() 리턴값을 doInBackground() 곳곳에서 체크하고, AsyncTask를 멤버 변수로 유지하고서 Activity의 onDes..
Looper와 Handler Looper? - (loop)+er 뭔가 반복해서 실행하는 것 - TLS(thread local storage)에 저장되고 꺼내어진다. - ThreadLocal 에 set() 메서드로 새로운 Looper을 추가하고, get() 메서드로 스레드별로 다른 Looper가 반환된다. - Loper 별로 MessageQueue를 가짐 Looper에게 MessageQueue란 Looper는 MessageQueue를 통해서 UI 작업에서 경합 상태를 해결한다. MessageQueue에서 꺼낸 Message가 null이 될 때는 Looper가 종료될 때이다. quit()와 quitSafely() 메서드 차이 둘 다 Looper를 종료시키는 메서드다. quit()는 아직 처리되지 않은 Message를 모두 제거한다. q..
안드로이드 호환성 모드 앱이 동작하는 안드로이드 버전을 지정하기 위해서는 minSdkVersion과 targetSdkVersion에 버전을 기재한다. 안드로이드 스튜디오에서는 build.gradle에 기재하여 AndroidManifest.xml의 내용을 오버라이드할 때가 많다. targetSdkVersion은 반드시 지정 targetSdkVersion을 명시하지 않으면 minSdkVersion과 동일한 값으로 지정된다. 그러면 호환성 모드 이슈를 겪을 가능성이 생긴다. targetSdkVersion을 지정한다는 의미는 해당 버전까지 테스트해서 앱을 실행하는 데 문제 없다는 의미이고, 그 버전까지는 호환성 모드를 쓰지 않겠다는 뜻이다. targetSdkVersion은 가급적 높게 지정 결론적으로 단말 버전에 따라 최신 기능을 쓸..
코루틴 컨텍스트 전환 초기 Cntinuation은 DispatchedContinuation으로 감싸여 있다. 여전히 Continuation이지만 Unconfined를 제외한 경우에, 필요에 따라 CorotineDispatcher로 전달할 수 있다. DispatchedTask를 전송한다. DispatchedTask는 Runnable로, withCoroutineContext()를 사용하여 적절한 컨텍스트를 설정하고, DispatchedContinuation으로부터 resume()와 resumeWithException() 함수를 호출한다. 따라서 실제 스레드 변경 작업은 CoroutineDispatcher에서 일어나지만, 실행 전에 연속체를 가로챌 수 있는 전체 파이프라인 덕분에 가능한 것이다. 서적 : 코틀린 동시성 프로그래밍
코루틴 디버깅 로그에서 코루틴 식별 디버깅 중에 코루틴을 식별할 필요가 있을 때가 있다. private fun threadName() = Thread.currentThread().name 위 코드를 사용해서 Thread를 식별할 수 있다. 코루틴에 특정 이름 설정 물론 코루틴에 특정 이름을 설정하는 방법도 있다. withContext(pool + CoroutineName("inner") { } 위처럼 CoroutineName을 통해 가능하다. CoroutineNeme은 컨텍스트 요소 이므로 + 연산자로 사용해 설정할 수 있다. 디버거 감시 추가 Debug Tool 창의 [Variables] 부분에 New Watch 버튼과 브레이크 포인트를 통해 스레드의 이름을 감시할 수 있다. Condition : Thread.cur..