연락처 앱 개발 - 3

kkomin·2023년 9월 7일
0

Android Studio

목록 보기
26/44
post-thumbnail

📷 사진추가

갤러리에서 선택한 사진으로 변경해주는걸 오늘 해결했다.. 같은 팀원 분이신 성수님이 해결해주셨는데, 진짜 너무 열받는다..

Dialog 이 자식 때문에!!!!!! 진짜 조금만 비틀어서 생각했으면 간단하게 해결할 수 있는 문제였는데!!!!!!!!! Dialog에 눈이 돌아버렸었네..아이고..


👀 Dialog 열기


🤷‍♀️ DialogFragment

이거 DialogFragment를 이용해주면 이전에 안되던 registerForActivityResult를 정말 간단하게 사용할 수 있더라..ㅎ


binding 변수 선언

  • private lateinit var binding : ActivityAddContact
  • private val binding by lazy { FragmentAddContact.inflate(layoutInflater)}

두 가지 방법으로 선언할 수 있는데 이 둘의 차이점이 뭐였는지 헷갈려서 다시 정리하고자 한다.


- lateinit var binding

private lateinit var binding으로 선언해줄 경우에는 lateinit으로 선언해 지연초기화 속성으로 선언함으로써, binding 변수를 추후 초기화할 수 있다.

단, binding = ActivityAddContactBinding.inflate(inflater, container, false)와 같이 사용 전에 반드시 초기화를 해줘야 한다!

즉, 초기화를 미루고 싶지만 초기화되지 않은 상태로 변수를 사용할 위험이 있는 경우에 유용하다 !


- val binding by lazy

해당 변수가 처음으로 사용될때 초기화되고 이전에 초기화되지 않은 경웅만 초기화를 하기 때문에 사용 전까지 초기화가 지연된다. 이를 이용해 변수 초기화를 편리하게 미룰 수 있고 필요한 시점에 초기화를 수행할 수 있다.

초기화 지연을 효과적으로 안전성을 중요하게 처리하고자 할 경우에 유용하다 !


onCreate / onCreateView ?

이전 코드에서는 onCreate를 이용했는데 Fragment에서는 onCreateView로 사용했네? 둘의 차이점이 뭘까?


- onCreate

Activity나 Fragment가 처음 생성될 때 호출된다. onCreate에서는 UI요소들을 생성하거나 초기화하지 않아야 한다. (에러가 발생할 수 있음.)

- onCreateView

Fragment에서 호출되며, Fragment의 레이아웃을 생성하고 초기화할 때 사용된다.

🚨 UI 조작은 onCreateView에서 진행할 것 !


💻 실행 결과

👉 뭔가 조금만 더 하면 될 것 같아서 이틀의 시간을 버린 결과 ?

만약 다음에도 이렇게 애뮬 내의 앱으로 이동하고 이 애뮬의 사진이나 데이터로 변환해주는 기능을 추가해야 한다면 신속하게 해낼 수 있을 것 같다..하하


⌚ Event 알림기능

Dialog를 통해 추가할 때 event를 설정하는 기능이 있는데 이를 이용해 5분 뒤 알람이라면, 5분뒤에 알림이 뜨게끔 해줄 것이다.

앗..? 레이아웃에 알람이 아니라 알림으로 수정해줘야겠다.. 알람과 알림은 엄연히 다른 것이니까..

❓ PendingIntent

Pending의 뜻은 보류, 임박한 등의 뜻이다. 즉, PendingIntent는 가지고 있는 Intent를 지금 당장 수행하지 않고 특정 시점(앱이 구동되고 있지 않을 경우)에 수행하도록 하는 것이다.

예를 들어 앱을 설치할 때 앱이 대용량이라면 다운로드를 기다리는 것보다 유튜브나 인터넷 서칭 등 다른 앱을 이용하는 사용자가 대다수이다.

그러므로 다운로드가 다 되었을 때 알리는 것이 훨씬 효율적이기 때문에 다운로드 완료 시 사용자에게 푸시알림을 보낼 때 PendingIntent를 이용해주면 된다.

추가적으로 PendingIntent를 이용해 푸쉬알림을 탭하면 앱이 실행된다.

근데, 일반 Intent로도 정상적으로 작동하지 않을까?

ㄴㄴ!! 다른 앱에서부터 내가 정의한 Intent를 실행한다는 뜻이기 때문에 이는 불가능하다. Intent는 같은 앱 내에서!

그럼 PendingIntent는 언제 쓰는게 좋을까?

  • Notification으로 Intent 작업을 수행할 경우 사용
  • launcher 위젯에서 Intent 작업을 수행할 경우 사용
  • AlarmManger을 통해 지정된 Intent 작업을 수행할 경우 사용

📄 사용방법

PendingIntentActivity, Service, BroadcastReceiver 등 컴포넌트의 유형에 따라 생성자를 호출하는 방식이 다르다.


📚 파라미터 정보

  1. Context 정보
  2. requestCode : PendingIntent를 가져올 때 구분용을 위한 고유 코드
  3. 실행할 Intent
  4. Flag
  • FLAG_CANCEL_CURRENT : 이전에 생성한 PendingIntent 취소 후 새로생성
  • FLAG_NO_CREATE : 이미 생성된 PendingIntent 존재 시 재사용
  • FLAG_ONE_SHOT : 해당 PendingIntent를 일회성으로 사용
  • FLAG_UPDATE_CURRENT : 이미 생성된 PendingIntent 존재 시 Extra Data만 갈아끼워 업데이트

💜 Handler

알림 예약기능을 구현할 때 사용한 Handler에 대해 한 번 정리해보자.

📜 UI 동작

일단 안드로이드의 UI처리는 싱글쓰레드 모델로 동작하고 메인 thread가 아닌 다른 thread에서 UI를 업데이트하는 등의 행위는 불가능하다. 이게 무슨 말이야?

fragment1, fragment2 레이아웃이 존재한다고 하자. 그러면 fragment2 레이아웃에서 fragment1의 TextView를 수정할 수 없다는 말이다.

즉, 메인 쓰레드에서는 UI 관련 동작이 가능하지만, 별도의 쓰레드에서는 UI 관련 동작이 불가능하다는 것이다. 다른 쓰레드에서 메인쓰레드로 결과를 전송한다면 동작이 가능하기 때문에 Thread 간의 통신을 구현해주면 된다.

이를 위해 우리가 사용하는 것은 LooperHandler이다. 기존의 싱글 쓰레드 환경을 이 두가지를 이용해 멀티 쓰레드 환경으로 구축할 수 있다.

💪 Handler

handler는 안드롱드에서 쓰레드 간의 통신 미 작업 스케줄링을 위한 클래스 중 하나이다. 기본적으로 메인 쓰레드에서 작업을 수행하도록 설계되어있으며, UI 갱신 및 지연 작업을 처리할 때 사용된다.

🖇️ Looper

안드로이드에서 Handler와 함께 사용하는 것으로 쓰레드 간의 메세지 큐와 작업 스케줄링을 관리할 수 있고, 쓸드가 무한 루프 내에서 대기하고 메세지나 Runnable 객체를 처리할 수 있도록 하는 역할을 한다.


⏰ 알림 예약

먼저, AddContactDialog에 handler를 선언해준다.

private val handler = Handler(Looper.getMainLooper())

예약 알람기능 함수를 하나 생성해줄건데 reservationNotification으로 설정해주고 기능을 구현해주면 된다.

그리고 알림채널을 생성하고 알림을 생성해주면 된다.

그리고, 이벤트 버튼을 하나만 누를 수 있도록 구현한 코드 하단에 handler의 postDelayed 함수를 이용해 알림 기능을 추가해주면 된다.

profile
소소한 코딩 일기

0개의 댓글