참고: 정돈되지 않은 포스팅입니다.
책 : 안드로이드 생존코딩 (오준석)
이 챕터의 내용은 변경점이 많아서 책을 따라가는 것이 아니라 최신 정보를 공부해야 한다.
저자님의 깃헙 참고 : github.com/junsuk5/kotlin-android
<사용 라이브러리>
Anko - 인텐트 구현에 도움을 줄 것
Glide - 이미지 로딩에 특화된 라이브러리 : 메모리 절약, 자연스러운 사진 로딩에 사용한다.
<새로 배운 개념>
ㅇ안드로이드 4대 컴포넌트
1. 액티비티 : 화면을 구성
2. 콘텐츠 프로바이더 : 데이터를 다른 앱에 공유
3. 브로드캐스트 리시버 : 앱, 기기가 발송하는 방송을 수신
4. 서비스 : 화면이 없고, 백그라운드 작업에 용이
ㅡㅡ데이터 접근ㅡㅡ
ㅇ콘텐츠 프로바이더
- 앱의 데이터 접근을 다른 앱에 허용하는 컴포넌트. 이걸로 사진 정보를 얻어올 수 있다. 외부 저장소에 있는 사진 데이터를 가져와야 하므로 '외부 저장소 읽기 권한'을 앱에 부여한다.
- contentResolver 객체를 사용해 데이터를 얻을 수 있다.
ㅇ권한
- 정상 권한 : 매니페스트에 권한을 추가하면 권한이 부여된다. 인터넷 권한 설정 등
- 위험 권한 : 실행 중에 사용자에게 권한을 요청해야 한다. 카메라, 외부저정소 권한, 문자, 위치정보 등.
권한이 필요한 작업을 수행할 때마다 권환이 있는지 확인해야 한다. ContextCompat.checkSelfPermission() 메서드 사용.
ㅇ저장소
- 내부 저장소 : OS설치된 영역 / 유저 접근x / 앱 사용정보와 데이터베이스
- 외부 저장소 : 기기연결하면 저장소로 인식되는 부분
ㅡㅡ화면의 구성ㅡㅡ
ㅇ프래그먼트
- 사용자 인터페이스의 모음
- File - New - Fragment 프래그먼트 생성(작성준비)
- 프래그먼트 여러개 조합으로 액티비티 하나 구성 가능 / 작성한 프래그먼트 재사용 가능
- 프래그먼트에도 액티비티처럼 생명주기가 있고, 역시 다양한 콜백 메서드가 있다.
- 액티비티처럼 하나의 클래스와 XML레이아웃 파일으로 구성된다.
프로그램 구성 간단 요약
ㅇ사진 정보를 가져와 경로 얻기 - 프로바이더 이용
ㅡ프로바이더에 대한 설명을 더 얻고싶다면..
안드로이드는 기본적으로 SQLite를 사용할 수 있도록 다양한 API를 제공한다.
안드로이드 4대 컴포넌트 중 하나,
Content Provider - 앱과 저장소 사이/ 서로 다른 앱 사이에서 데이터 접근을 쉽게 하도록 관리한다. 어플리케이션의 요청이 들어오면 데이터를 제공하는 등..
다른 앱의 데이터에 접근하려면 URI를 이용하여 컨텐트 리졸버를 통해, 다른 앱의 컨텐트 프로바이더에게 데이터를 요청한다. 요청받은 컨텐트 프로바이더는 URI 확인 후 적절한 데이터를 꺼내어 컨텐트 리졸버에게 전달.
They encapsulate data and provide it to applications through the single ContentResolver interface.
컨텐트 리졸버는 컨텐트 프로바이더 간의 중개자 역할 느낌.
ㅇ외부저장소 읽기 권한 추가 : 매니페스트에 추가
ㅡ> 콘텐츠 제공자 권한에 대한 문서 : https://developer.android.com/guide/topics/providers/content-provider-basics?hl=ko#Permissions
ㅇ권한의 확인과 요청, 그에 대한 응답 처리
ㅇ액티비티, 프래그먼트 구성하기, 어댑터 개념
<권한과 콘텐츠 프로바이더에 관한 구성을 좀 더 자세히 정리해보기>
<기타 세부적인 정리>
activity에 MainActivity를 전달해야 할 때 this라고 쓰는 경우와 this@MainActivity하고 명시해주는 경우의 차이점
그냥 this라고 쓸 경우에 코드가 존재하는 위치에 따라 의도한 객체가 아닌 다른 객체를 받는 경우가 있었다. 그래서 저렇게 참조할 액티비티를 확실하게 써주는 경우도 있는 것 같다.
예 아니요 선택지를 띄우는 방법
alert(msg,title
yesButton{ ... }
noButton{ ... }
}.show()
Cursor 객체 선언 - 외부저장소 uri 지정
contentResolver클래스의 query()메서드는 Cursor객체를 반환한다.
인자2: 가져올 데이터의 항목 / 모든 항목: null
인자3: 가져올 데이터 조건 / 모든 조건: null
인자4: 인자3과 조합한 조건 / 사용안한다면 null
인자5: 정렬 방법 지정
+ 더 자세히 하려면 SQL문법 지식이 필요하다고 한다.
8.2.5 resource 자동관리
자바 7 부터는 try-with-resource란 구문으로 closable을 구현한 객체에 대해서 자동 close() 호출을 보장 합니다.
코틀린에서의 try문에서는 위 구문을 사용할수 없습니다. (1.6 호환이 목적이므로ㅠ.ㅠ)
그 대신 use 라는 함수를 기본 라이브러리가 제공해 줍니다.
fun readFirstLineFromFile(path: String): String { BufferedReader(FileReader(path)).use { br -> return br.readLine() } }
use를 쓰게되면 finally에서 close를 강제로 해야 된다든가 하는 번거로움이 없어집니다.
안드로이드에서는 cursor를 쓸때 정말 유용합니다.
use는 exception이 발생하여 비정상 종료 되더라고 close를 호출하도록 되어있으니 안심하고 사용해도 됩니다.
출처: https://tourspace.tistory.com/120 [투덜이의 리얼 블로그]
사진 정보를 가지고 있는 Cursor 객체에서 사진 경로 uri 문자열 얻기
그런데 이건 String으로 uri를 받았을 때 사용한거고, 변경점에 따라 uri를 Uri로 받을 때에는
.getParcelable<Uri>()를 사용했다.
kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/mutable-list-of.html
프래그먼트 작성
하나의 사진을 꽉 차게 보여주는 프래그먼트를 작성하려고 한다. (하던대로 하면 된다)
이 프래그먼트에서 이미지뷰를 하나 만들었는데, 아까 얻은 사진의 정보(URI)를 이 이미지뷰에 전달해야 한다.
ㅇsetImageURI() 메서드
ㅇGlide 라이브러리 사용
- 미사용 리소스 자동 해제, 메모리 효율적 관리
- 이미지를 비동기로 로딩하여 UI 끊김 없음
- 역시 그레이들 파일에 의존성을 추가해야 한다.
- 이전에는 한 줄로 끝났는데 저장소 정책이 변경되면서 우회하는 코드를 추가해야 했다.
아ㅠㅠ 완성하는데 꽤 오래 걸리겠다.
타입이 매치되지 않는 에러가 생겼는데 왜지??
.
.
.
수정했다. 기존 예제는 어댑터가 FragmentStatePagerAdapter를 상속했는데,
FragmentStateAdapter를 상속하는 걸로.. (ViewPager2에서 이걸로 변경되었다는 정보를 듣고 아예 바꿨다.)
그리고 인자 타입으로는 FragmentActivity로 정했는데..(그래야 오류가 안나길래)
[모호한 개념 정리]
ㅇ도대체 FramgmentManager는 언제 쓰는거고 FragmentActivity는 언제 쓰는걸까
ㅇFragmentStateAdapter을 확장할 때랑 RecyclerView.adapter를 확장할 때는 어떤 용도의 차이가 있나, 지금 이 프로젝트에서는 ViewPager2를 기반으로 했는데 여기서 RecyclerView를 기반으로 하려면 어떻게 작성을 해야 하나
ㅇ인자로 넣는 객체타입은 어떻게 판단해야 하나
근데 아직 개념이 모호하다. 따로 포스팅하여 정리를 해봐야겠다
[아직 정리중]
꺄!!!! >o<
우왓씨ㅠㅠㅠㅠㅠㅠㅠㅠㅠㅠ드디어 됐다!!! 휴!! 해결했다!! 와!! 며칠이 걸린 거니!
이렇게 혼자 해결해본적이 처음이라 엄청나게 신기하다. 이 해결을 위해서 예제도 이것저것 많이 봤고 검색도 많이 해보고 안드로이드 공식문서도 읽고 참 좋은 경험이 되었다. 나 진짜 초짜구나~ 이런 뷰 설정 하나에도 헤메고 ㅠㅡㅠ
아니 또 다해놓고 계속 헤멨던게 뭐냐면 어댑터파일을 layout폴더 안에 만들어놨던 거다.. 그래서 자꾸 파일이름이 xml이어야 한다는거다.. 그래서 맨처음에는 잉??잉?? 이러고 있다가 잠깐 곰곰이 생각해보니까 아 레이아웃폴더에 들어가있네 이자슥이!! ㅎㅎㅎ 아오~~진촤~~♥♥(<--김선호님 그거 맞다~! ㅎㅅㅎ)
아오!! 올바른 폴더 com.example.mygallery에 옮기고 딱! 빨간줄 사라질때 너무 심쿵했다.
이제 기기에서 실행해보자 하고 run 눌렀을 때.. 진짜.. 두 손을 모으고 제발..! 제발..!을 외쳤다 ㅠㅠ 디버그도 오래걸려서 진짜 오랫동안 손을 모으고 제발.....! 제발...! 을 외쳤다. 아직두 떨리네 후덜덜
정말... 딱 install 뜨자마자 눈이 동그래지고 다시 제발..!을 외쳤다. 그리고 lunching 뜰때 폰화면을 바라보고 또 으으으 제발 제발 제발요...!! 를 마음속으로 매우 간절하게 외쳤다.
.
.
.
그리고 사진이 똬앗!!! ㅠㅠㅠㅠ 떴다 ㅠㅠ 제일 최근에 저장한 사진이...... 신이시여... 진짜 그리고 3초 뒤에 정확히 다음사진으로 땃 땃 넘어가는데 정말!! 너무 다행이다.. 계속 전자액자 챕터에서 묶여있으면서 많은 것을 배웠다. 그리고 아직 더 이 챕터에서 배운 뷰에 대해 정리해야한다. 휴 이제 지금 작성한 올바른 코드 구성을 공부하고, ViewPager2랑 RecyclerView, 그리고 어댑터에 대한 모호한 개념을 다시 정리해야겠다. 이 포스팅은 여기서 끝내고 새로운 포스팅으로 뷰 학습을 시작하겠다.
'JAVA' 카테고리의 다른 글
[안드로이드 스튜디오] Layout 개념 기본 정리 / View binding (0) | 2021.01.20 |
---|---|
안드로이드 - ViewPager2를 이용한 슬라이더 학습 (0) | 2021.01.19 |
[안드로이드] ViewPager, ViewPager2, RecyclerView, Fragment [작성중] (0) | 2021.01.18 |
안드로이드 - 챕터8, 수평 측정기 (0) | 2021.01.14 |
[안드로이드] 늦은 초기화 방법 (0) | 2021.01.12 |