Basics

Published: by

View

onMeasure

Measure는 '측정하다'라는 뜻이다.

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)

onMeasure는, 뷰와 그 내용을 측정하여 측정 된 너비와 측정 된 높이를 결정한다.

onLayout

protected void onLayout (boolean changed, int left, int top, int right, int bottom)

onLayout은 뷰가 각 자식에 크기와 위치를 할당해야 할 때 레이아웃에서 호출된다. 자식이 있는 파생 클래스는이 메서드를 재정 의하여 각 자식에 대해 레이아웃을 호출해야 한다.

onDraw

protected void onDraw (Canvas canvas)

드로잉을 위해 구현하면 된다.

View의 생명주기

RxJava2

Observable, Single, Flowable, Maybe, Completable

형태들의 차이점

RxJava 1.x에서는 Observable과 Single 두 가지의 형태가 존재했다. Observable은 무한한 데이터를 발행 할 수 있는 반면 Single은 한번에 하나의 데이터를 발행 할 수 있다.

RxJava 2.x에서는, Observable과 Single 두 가지 형태 모두 존재하고 추가로 Flowable, Maybe가 존재한다. Flowable, Maybe는 기존 Observable을 세분화한 형태라고 볼 수 있다.

Maybe는 데이터가 발행될 수 있거나 혹은 발행되지 않고도 완료되는 경우에 사용한다. 구체적으로 데이터가 발행되면 onSuccess로 구독하고 데이터가 발행되지 않는다면 onSuccess호출되지 않고 onComplete가 호출된다.

Flowable은 Observable에서 데이터가 발행되는 속도가 구독자가 처리하는 속도보다 현저하게 빠른 경우 발생하는 배압(Back pressure) 이슈에 대응하는 기능을 추가로 제공한다. RxJava 1.x에서는 Flowable이 Observable에 포함되어 있었으나 RxJava 2.x에서 분리했다.

Completable은, onCompleted()onError(throwable) 만을 가진다. 비동기 처리 후 반환되는 결과가 없는 경우 사용하면 된다.

RxJava Cold & Hot

Hot 이면 만들어 졌을때 emit(통지) 되기 시작하고, 나중에 구독하는 Observer 는 중간에 아무대나 관찰을 시작 할수 있습니다. Cold 는 반대로 Observer 가 구독을 시작 할 때까지 기다리고, 구독 시작 할때 아이템들을 emit(통지) 하기 시작합니다. 따라서 Observer 가 모든 item 을 구독할수 있는 보장이 됩니다.

Service

IntentService 란?

https://android.keicode.com/basics/services-intentservice.php

Service와는 다르게 워커쓰레드에서 동작한다. 여러번(작업) 호출하면 큐에 작업을 쌓는다. 작업을 순차적으로 처리한다. 작업이 완료되면 자동 종료한다.

사용 예

여러 파일을 다운로드해야 할때 사용한다.

(Service) 왜 필요한가?

Service는 안드로이드 주요 컴포넌트다. Activity컴포넌트와 분리되어 있기 때문에 Activity가 종료되어도 작업을 계속 진행할 수 있다. 하지만, 워커쓰레드는 Activity에 포함되어 있기 때문에 Activity가 종료되면 문제가 생길 수 있다.

IntentService와 Service의 차이

https://medium.com/@joongwon/android-service%EC%99%80-thread%EC%9D%98-%EC%B0%A8%EC%9D%B4-a9175016450

https://code.i-harness.com/ko-kr/q/7694bb

dispatchTouchEvent, onTouchEvent

https://moka-a.github.io/android/touch-event-transfer/

http://dktfrmaster.blogspot.com/2016/09/blog-post_26.html

http://iw90.tistory.com/186

https://code-examples.net/ko-kr/q/924570

SparseArray

https://developer88.tistory.com/91

http://log.hanjava.net/post/30231660090/map-hashmap-%EA%B7%B8%EB%A6%AC%EA%B3%A0-sparsearray

Throwable, Error, Exception

Java 예외(Exception) 처리에 대한 작은 생각

http://sjh836.tistory.com/122

자바 제네릭에 대하여

http://happinessoncode.com/2017/05/21/java-generic-and-variance-1/

http://devbox.tistory.com/entry/Java-%EC%A0%9C%EB%84%A4%EB%A6%AD

알고리즘 복잡도

http://ledgku.tistory.com/33

https://m.blog.naver.com/demonic3540/221229805234

  • 공간 복잡도(Space Complexity) : 알고리즘에 사용되는 메모리 공간의 총량
  • 시간 복잡도(Time Complexity) : 알고리즘에 사용되는 연산횟수의 총량(시간이 아니다)

일반적으로 알고리즘을 평가할 때 메모리의 사용량보다 실행속도에 초점을 맞춘다.

HandlerThread

https://academy.realm.io/kr/posts/android-thread-looper-handler/

https://blog.mindorks.com/android-core-looper-handler-and-handlerthread-bd54d69fe91a

Serializable, Parcelable

Serializable과 Parcelable은 직렬화 해서 보내고, 역질렬화해서 받는 것을 도와준다. Serializable은 Java에서 제공하고 Parcelable은 안드로이드에서 제공한다.

구현은 Serializable이 Parcelable에 비해 간편하다. 하지만, 성능은 일반적으로 Parcelable이 좋다. Java의 Reflection을 사용하지 않기 때문이다. :

Parcelable은 IPC(프로세스간 통신)를 이용하기 때문입니다. 프로세스들 사이에서 서로 데이터를 주고 받는것을 IPC라고 하는데요. 프로세스간의 메모리 영역을 공유 할 수 없기에 Parcelable인터페이스는 커널메모리를 통해 데이터를 다른 프로세스로 전달하는 통로를 만들어 줍니다.

그러나!!!!

Serializable을 빠르게 구현(?)해 주면 되면 성능이 역전된다.[https://medium.com/@limgyumin/parcelable-vs-serializable-%EC%A0%95%EB%A7%90-serializable%EC%9D%80-%EB%8A%90%EB%A6%B4%EA%B9%8C-bc2b9a7ba810](https://medium.com/@limgyumin/parcelable-vs-serializable-정말-serializable은-느릴까-bc2b9a7ba810)

기본형 자료타입과 Wrapper의 차이

Ingeter, Long, Double…

http://hyeonstorage.tistory.com/168

http://includestdio.tistory.com/1

http://tcpschool.com/java/java_api_wrapper

https://www.w3resource.com/java-tutorial/java-wrapper-classes.php

equals()와 hashCode()

equals 는 두 객체의 내용이 같은지, 동등성(equality) 를 비교하는 연산자

hashCode 는 두 객체가 같은 객체인지, 동일성(identity) 를 비교하는 연산자

http://anster.tistory.com/160

https://nesoy.github.io/articles/2018-06/Java-equals-hashcode

Android Lint

코드에 구조적 문제가 없는지 확인해 주는 것

https://developer.android.com/studio/write/lint?hl=ko#manuallyRunInspections

Android Compat?

이전 버전과의 호환성

지원 라이브러리를 사용하면 이전 버전의 Android 플랫폼에서 실행 중인 앱이 새 버전의 플랫폼에서 사용 가능하게 된 기능을 지원할 수 있습니다. 예를 들어, 프레임워크 클래스에 의존하는 Android 5.0(API 레벨 21) 이전 버전에서 실행 중인 앱은 해당 버전의 Android 프레임워크가 머티리얼 디자인을 지원하지 않기 때문에 머티리얼 디자인 요소를 표시할 수 없습니다. 그러나 앱이 지원 라이브러리의 appcompat 라이브러리를 통합하면 해당 앱이 머티리얼 디자인 지원을 비롯한 API 레벨 21에서 사용 가능한 다양한 기능에 액세스할 수 있습니다. 따라서 앱이 다양한 플랫폼 버전에서 훨씬 일관적인 경험을 제공할 수 있습니다.

예를 들어) ContextCompat.getColor()..

[https://developer.android.com/topic/libraries/support-library/?hl=ko]{https://developer.android.com/topic/libraries/support-library/?hl=ko}{:target="_blank"}

Save, Restore

Android Profiler(앱 성능 측정)

https://developer.android.com/studio/profile/android-profiler?hl=ko

메모릭 사례

안드로이드의 메모리 누수 패턴

static TextView label;
static Activity activity = null;
		...
		SomeSingletonManager someSingletonManager = null;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {        
        someSingletonManager = SomeSingletonManager.getInstance(this);
    }
    ...
		...
		private static SomeInnerClass someInnerClass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_leak_static_reference_to_inner_class);

        if (someInnerClass == null) {
            someInnerClass = new SomeInnerClass();
        }
    }

    class SomeInnerClass {
    }
	...

메모리 구조

http://tcpschool.com/c/c_memory_structure

메모리 구조

멀티스레드에서 주의할점

  • Synchronized
  • volatile 키워드로 선언된 변수 값을 바꾸면 다른 스레드에서 항상 최신 값을 읽어갈 수 있다.
  • 쓰레드의 실행 순서를 정의하고, 이 순서에 반드시 따르도록 하는 것
  • 메모리 접근에 있어서 동시 접근을 막는 것

스택오버플로에러(StackOverflowError)

사용가능한 메모리(Stack)가 없을 때 발생한다. 손쉽게 테스트를 할 수 있다. 메서드 안에 어떤 타입의 변수 하나를 설정하고 변수를 무한히 증가시키히는 반복문을 넣으면 StackOverFlow 에러를 볼 있다.

https://docs.oracle.com/javase/7/docs/api/java/lang/StackOverflowError.html

싱크로나이즈드

스레드 동기화 synchronized에 관해서

Sticky intent(끈적끈적한 인텐트)

About Android Sticky Broadcast Intent

Sticky intent (또는 Sticky broadcast intent)

Android Looper

https://academy.realm.io/kr/posts/android-thread-looper-handler/

https://itmining.tistory.com/5

https://jw910911.tistory.com/54

https://jungwoon.github.io/android/2019/09/25/Handler-Looper/

코틀린 Inline과 Reified

Background service와 Foreground service

서비스에는 세 가지 유형이 있습니다.

  • 포그라운드

    포그라운드 서비스는 사용자에게 잘 보이는 몇몇 작업을 수행합니다. 예를 들어 오디오 앱이라면 오디오 트랙을 재생할 때 포그라운드 서비스를 사용합니다. 포그라운드 서비스는 알림을 표시해야 합니다. 포그라운드 서비스는 사용자가 앱과 상호작용하지 않을 때도 계속 실행됩니다.

  • 백그라운드

    백그라운드 서비스는 사용자에게 직접 보이지 않는 작업을 수행합니다. 예컨대 어느 앱이 저장소를 압축하는 데 서비스를 사용했다면 이것은 대개 백그라운드 서비스입니다.참고: 앱이 API 레벨 26 이상을 대상으로 한다면 앱이 포그라운드에 있지 않을 때 시스템에서 백그라운드 서비스 실행에 대한 제한을 적용합니다. 이와 같은 경우에서는 대부분 앱이 예약된 작업을 사용해야 합니다.

  • 바인드

    애플리케이션 구성 요소가 bindService()를 호출하여 해당 서비스에 바인딩되면 서비스가 바인딩됩니다. 바인딩된 서비스는 클라이언트-서버 인터페이스를 제공하여 구성 요소가 서비스와 상호작용하게 하며, 결과를 받을 수도 있고 심지어 이와 같은 작업을 여러 프로세스에 걸쳐 프로세스 간 통신(IPC)으로 수행할 수도 있습니다. 바인딩된 서비스는 또 다른 애플리케이션 구성 요소가 이에 바인딩되어 있는 경우에만 실행됩니다. 여러 개의 구성 요소가 서비스에 한꺼번에 바인딩될 수 있지만, 이 모든 것에서 바인딩이 해제되면 해당 서비스는 소멸됩니다.

https://developer.android.com/guide/components/services?hl=ko

What is IoC?

의미

IoC(제어의 역전)이란, 객체의 생성, 생명 주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미하는 디자인패턴으로, 프레임워크에서 개발자의 코드에 객체를 주입함으로써 개발자가 신경써야 할 코드를 줄이는 전략.

What is DI?

의미

의존성 주입(Dependency Injection)

장점

  1. 재사용성을 높여줍니다.
  2. 테스트에 용이하죠.
  3. 코드도 단순화 시켜줍니다.
  4. 종속적이던 코드의 수도 줄여줍니다.
  5. 왜 사용하는 지 파악하기가 수월합니다. 코드를 읽기 쉬워지는 점이 있습니다.
  6. 종속성이 감소합니다. 구성 요소의 종속성이 감소하면, 변경에 민감하지 않습니다.
  7. 결합도(coupling)는 낮추면서 유연성과 확장성은 향상시킬 수 있습니다.
  8. 객체간의 의존관계를 설정할 수 있습니다.
  9. 객체간의 의존관계를 없애거나 줄일 수 있습니다.

What is Service Locator?

Service locator vs Dependecy injection

서비스 로케이터와 DI와의 차이는 무엇인가?

간단한 개념에 따라 Service LocatorDI 컨테이너의 차이점을 명확하게 이해할 수 있다.

  • Service Locator는 소비자에서 사용되며 직접 소비자의 요청에 따라 일부 스토리지에서 ID별로 서비스를 가져옵니다.
  • DI 컨테이너는 외부 어딘가에 있으며 일부 스토리지에서 서비스를 가져와 소비자에게 푸시합니다 (생성자나 메소드를 통해)

그러나 구체적인 소비자 사용 상황에서만 이러한 차이점에 대해 이야기 할 수 있습니다. 서비스 로케이터 및 DI 컨테이너가 컴포지션 루트에 사용되는 경우 거의 비슷합니다.

https://stackoverflow.com/questions/1557781/whats-the-difference-between-the-dependency-injection-and-service-locator-patte

Fragment에서 setArgument하는 이유

이 프래그먼트에 대한 구성 인수를 제공하십시오. 여기에 제공된 인수는 프래그먼트 파괴 및 생성에도 유지됩니다.

이는, 안드로이드 시스템에 의해 프래그먼트가 제거 되고 다시 생성할때 제공된 인수 값을 다시 사용할 수 있다는 것을 뜻한다.

조각을 사용하려면 먼저 인스턴스가 필요합니다. 안드로이드는 YourFragment() ( 인자 없음 생성자)를 호출하여 프래그먼트의 인스턴스를 생성합니다. 안드로이드는 어느 것을 사용할 지 알 수 없으므로 여기서 작성한 오버로드 된 생성자는 무시됩니다.

액티비티의 수명 기간 동안 조각은 위와 같이 생성되어 Android에서 여러 번 파괴됩니다. 즉, 조각 객체 자체에 데이터를 저장하면 조각이 파기되면 데이터가 손실됩니다.

이 문제를 해결하기 위해 Android에서는 Bundle (setArguments() 호출)을 사용하여 데이터를 저장하고 YourFragment에서 액세스 할 수 있도록 요청합니다. 인수 bundle은 Android에 의해 보호되므로 persistent 로 보장됩니다.

이 번들을 설정하는 한 가지 방법은 정적 newInstance 메소드를 사용하는 것입니다.

참고 : [https://www.it-swarm.dev/ko/android/%EC%83%88%EB%A1%9C%EC%9A%B4-android-fragment%EB%A5%BC-%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%ED%99%94%ED%95%98%EB%8A%94-%EB%AA%A8%EB%B2%94-%EC%82%AC%EB%A1%80/942373516/](https://www.it-swarm.dev/ko/android/새로운-android-fragment를-인스턴스화하는-모범-사례/942373516/)

함수형 프로그래밍의 특장점

메모리 프로파일러 사용 경험

  • RecyclerView에서 배경 바뀌면서 버벅이던 현상 발견
  • 메모리 프로파일러 실행
  • 메모리가 올라가는 것을 그래프로 확인(이미지, 어떻게 이미지인 것을 알았지?)
  • 뷰홀더가 재사용 하는 시점에 onViewRecycled가 호출된다는 것을 확인
  • onViewRecycled에서 이미지를 메모리에서 clean 해주고, 사용한 RxJava를 clear 해주었다.
public void onViewRecycled() {
	Glide.get(itemView.getContext()).clearMemory(); // 사용한 이미지
	clearDispose(); // rx
}