갤러리에서 선택한 사진으로 변경해주는걸 오늘 해결했다.. 같은 팀원 분이신 성수님이 해결해주셨는데, 진짜 너무 열받는다..
Dialog 이 자식 때문에!!!!!! 진짜 조금만 비틀어서 생각했으면 간단하게 해결할 수 있는 문제였는데!!!!!!!!! Dialog에 눈이 돌아버렸었네..아이고..
이거 DialogFragment를 이용해주면 이전에 안되던 registerForActivityResult를 정말 간단하게 사용할 수 있더라..ㅎ
private lateinit var binding : ActivityAddContact
private val binding by lazy { FragmentAddContact.inflate(layoutInflater)}
두 가지 방법으로 선언할 수 있는데 이 둘의 차이점이 뭐였는지 헷갈려서 다시 정리하고자 한다.
private lateinit var binding
으로 선언해줄 경우에는lateinit
으로 선언해 지연초기화 속성으로 선언함으로써,binding
변수를 추후 초기화할 수 있다.
단,
binding = ActivityAddContactBinding.inflate(inflater, container, false)
와 같이 사용 전에 반드시 초기화를 해줘야 한다!
즉, 초기화를 미루고 싶지만 초기화되지 않은 상태로 변수를 사용할 위험이 있는 경우에 유용하다 !
해당 변수가 처음으로 사용될때 초기화되고 이전에 초기화되지 않은 경웅만 초기화를 하기 때문에 사용 전까지 초기화가 지연된다. 이를 이용해 변수 초기화를 편리하게 미룰 수 있고 필요한 시점에 초기화를 수행할 수 있다.
초기화 지연을 효과적으로 안전성을 중요하게 처리하고자 할 경우에 유용하다 !
이전 코드에서는 onCreate를 이용했는데 Fragment에서는 onCreateView로 사용했네? 둘의 차이점이 뭘까?
Activity나 Fragment가 처음 생성될 때 호출된다. onCreate에서는 UI요소들을 생성하거나 초기화하지 않아야 한다. (에러가 발생할 수 있음.)
Fragment에서 호출되며, Fragment의 레이아웃을 생성하고 초기화할 때 사용된다.
🚨 UI 조작은 onCreateView에서 진행할 것 !
👉 뭔가 조금만 더 하면 될 것 같아서 이틀의 시간을 버린 결과 ?
만약 다음에도 이렇게 애뮬 내의 앱으로 이동하고 이 애뮬의 사진이나 데이터로 변환해주는 기능을 추가해야 한다면 신속하게 해낼 수 있을 것 같다..하하
Dialog를 통해 추가할 때 event를 설정하는 기능이 있는데 이를 이용해 5분 뒤 알람이라면, 5분뒤에 알림이 뜨게끔 해줄 것이다.
앗..? 레이아웃에 알람이 아니라 알림으로 수정해줘야겠다.. 알람과 알림은 엄연히 다른 것이니까..
Pending
의 뜻은 보류, 임박한 등의 뜻이다. 즉, PendingIntent
는 가지고 있는 Intent
를 지금 당장 수행하지 않고 특정 시점(앱이 구동되고 있지 않을 경우)에 수행하도록 하는 것이다.
예를 들어 앱을 설치할 때 앱이 대용량이라면 다운로드를 기다리는 것보다 유튜브나 인터넷 서칭 등 다른 앱을 이용하는 사용자가 대다수이다.
그러므로 다운로드가 다 되었을 때 알리는 것이 훨씬 효율적이기 때문에 다운로드 완료 시 사용자에게 푸시알림을 보낼 때 PendingIntent
를 이용해주면 된다.
추가적으로 PendingIntent
를 이용해 푸쉬알림을 탭하면 앱이 실행된다.
근데, 일반 Intent로도 정상적으로 작동하지 않을까?
ㄴㄴ!! 다른 앱에서부터 내가 정의한
Intent
를 실행한다는 뜻이기 때문에 이는 불가능하다. Intent는 같은 앱 내에서!
그럼 PendingIntent는 언제 쓰는게 좋을까?
Notification
으로Intent
작업을 수행할 경우 사용launcher
위젯에서Intent
작업을 수행할 경우 사용AlarmManger
을 통해 지정된Intent
작업을 수행할 경우 사용
PendingIntent
는 Activity
, Service
, BroadcastReceiver
등 컴포넌트의 유형에 따라 생성자를 호출하는 방식이 다르다.
알림 예약기능을 구현할 때 사용한 Handler에 대해 한 번 정리해보자.
일단 안드로이드의 UI처리는 싱글쓰레드 모델로 동작하고 메인 thread가 아닌 다른 thread에서 UI를 업데이트하는 등의 행위는 불가능하다. 이게 무슨 말이야?
fragment1, fragment2 레이아웃이 존재한다고 하자. 그러면 fragment2 레이아웃에서 fragment1의 TextView를 수정할 수 없다는 말이다.
즉, 메인 쓰레드에서는 UI 관련 동작이 가능하지만, 별도의 쓰레드에서는 UI 관련 동작이 불가능하다는 것이다. 다른 쓰레드에서 메인쓰레드로 결과를 전송한다면 동작이 가능하기 때문에 Thread 간의 통신을 구현해주면 된다.
이를 위해 우리가 사용하는 것은 Looper
와 Handler
이다. 기존의 싱글 쓰레드 환경을 이 두가지를 이용해 멀티 쓰레드 환경으로 구축할 수 있다.
handler는 안드롱드에서 쓰레드 간의 통신 미 작업 스케줄링을 위한 클래스 중 하나이다. 기본적으로 메인 쓰레드에서 작업을 수행하도록 설계되어있으며, UI 갱신 및 지연 작업을 처리할 때 사용된다.
안드로이드에서 Handler와 함께 사용하는 것으로 쓰레드 간의 메세지 큐와 작업 스케줄링을 관리할 수 있고, 쓸드가 무한 루프 내에서 대기하고 메세지나 Runnable 객체를 처리할 수 있도록 하는 역할을 한다.
먼저, AddContactDialog에 handler를 선언해준다.
private val handler = Handler(Looper.getMainLooper())
예약 알람기능 함수를 하나 생성해줄건데 reservationNotification으로 설정해주고 기능을 구현해주면 된다.
그리고 알림채널을 생성하고 알림을 생성해주면 된다.
그리고, 이벤트 버튼을 하나만 누를 수 있도록 구현한 코드 하단에 handler의 postDelayed 함수를 이용해 알림 기능을 추가해주면 된다.