Android Studio Development Essentials: Android 7 Edition Copyright c 2016 Neil Smyth. All rights reserved. Korean Translation Copyright c 2017 by J-Pub. co. The Korean edition is published by arrangement with Neil Smyth through Agency-One, Seoul. 이책의한국어판저작권은에이전시원을통해저작권자와의독점계약으로제이펍출판사에있습니다. 신저작권법에의해한국내에서보호를받는저작물이므로무단전재와무단복제를금합니다. 1쇄발행 2017년 8월 11일지은이닐스미스옮긴이심재철펴낸이장성두펴낸곳제이펍출판신고 2009년 11월 10일제406-2009 - 000087호주소경기도파주시회동길 159 3층 3-B호전화 070-8201 - 9010 / 팩스 02-6280 - 0405 홈페이지 www.jpub.kr / 원고투고 jeipub@gmail.com 독자문의 readers.jpub@gmail.com / 교재문의 jeipubmarketer@gmail.com 편집부이민숙, 황혜나, 이슬, 이주원 / 소통 기획팀민지환, 현지환 / 회계팀김유미교정 교열장성두 / 본문디자인이민숙 / 표지디자인미디어픽스용지신승지류유통 / 인쇄해외정판사 / 제본광우제책사 ISBN 979-11 - 85890-78 - 4 (93000) 값 37,000원 이책은저작권법에따라보호를받는저작물이므로무단전재와무단복제를금지하며, 이책내용의전부또는일부를이용하려면반드시저작권자와제이펍의서면동의를받아야합니다. 잘못된책은구입하신서점에서바꾸어드립니다. 제이펍은독자여러분의아이디어와원고투고를기다리고있습니다. 책으로펴내고자하는아이디어나원고가있으신분께서는책의간단한개요와차례, 구성과저 ( 역 ) 자약력등을메일로보내주세요. jeipub@gmail.com
드리는말씀 이책은 핵심만골라배우는안드로이드스튜디오 & 프로그래밍 의최신개정판입니다. 이책에기재된내용을기반으로한운용결과에대해저 / 역자, 소프트웨어개발자및제공자, 제이펍출판사는일체의책임을지지 않으므로양해바랍니다. 이책에기재한회사명및제품명은각회사의상표및등록명입니다. 이책에서는 TM, C, R 등의기호를생략하고있습니다. 이책에서사용하고있는실제제품버전은독자의학습시점에따라책의버전과다를수있습니다. 이책의원서는안드로이드스튜디오 2.3 과안드로이드 7( 누가 ) 버전으로작성되었습니다만, 번역서는안드로이드스튜디오 3.0 Canary 8 과안드로이드 8.0 버전에맞춰업데이트하여출간합니다. 제이펍의다른책들과는달리이책은빠른출간을위해베타리딩을진행하지않고출간합니다. 이책에나오는안드로이드스튜디오예제프로젝트파일과역자가집필한특별부록 Kotlin( 코틀린 ) 핵심파악하기 (PDF) 는다음의사 이트에서다운로드할수있습니다. - https://github.com/jpub/androidstudio3 책의내용과관련된문의사항은옮긴이나출판사로연락주시기바랍니다. - 옮긴이 : jcspro@hanafos.com - 출판사 : readers.jpub@gmail.com
차례 xxvi CHAPTER 1 CHAPTER 2 CHAPTER 3 개요 _ 1 1.1 안드로이드스튜디오의장점 2 1.2 소스코드다운로드하기 3 1.3 단축키와코드표기 4 1.4 안드로이드스튜디오최신버전사용하기 4 1.5 독자 A/S 5 1.6 오탈자 5 안드로이드스튜디오개발환경구성하기 _ 6 2.1 개발시스템요구사항 6 2.2 자바 JDK 설치하기 7 2.3 리눅스에서설치하기 9 2.4 안드로이드스튜디오패키지다운로드하기 11 2.5 안드로이드스튜디오설치하기 11 2.6 안드로이드스튜디오설정위저드 17 2.7 가장최신버전의안드로이드 SDK 패키지설치하기 18 2.8 명령행에서안드로이드 SDK 도구사용하기 22 2.9 안드로이드스튜디오와 SDK 버전업그레이드하기 26 2.10 안드로이드 SDK와 NDK 및자바 JDK 경로변경하기 26 2.11 요약 27 안드로이드스튜디오로첫번째애플리케이션만들기 _ 28 3.1 새로운안드로이드프로젝트생성하기 28 3.2 프로젝트와 SDK 설정정의하기 30 3.3 액티비티생성하기 33 3.4 애플리케이션변경하기 34 3.5 레이아웃과리소스파일살펴보기 42 3.6 요약 45 차례 v
CHAPTER 4 CHAPTER 5 CHAPTER 6 CHAPTER 7 안드로이드스튜디오 UI 둘러보기 _ 46 4.1 웰컴스크린 46 4.2 메인창 47 4.3 도구창 50 4.4 안드로이드스튜디오의단축키 55 4.5 스위처와최근파일기능을이용한내비게이션 55 4.6 안드로이드스튜디오테마변경하기 56 4.7 요약 57 안드로이드스튜디오에서 AVD 생성하기 _ 58 5.1 AVD 개요 58 5.2 새로운 AVD 생성하기 60 5.3 에뮬레이터시작하기 66 5.4 AVD에서애플리케이션실행하기 66 5.5 Run/Debug 구성 68 5.6 실행중인애플리케이션중단시키기 69 5.7 명령행에서 AVD 조회하기 70 5.8 AVD 구성파일들 72 5.9 AVD의위치이동과이름변경 72 5.10 Intel HAXM 사용으로에뮬레이터성능향상시키기 73 5.11 요약 74 안드로이드스튜디오 AVD 에뮬레이터사용과구성하기 _ 75 6.1 에뮬레이터환경 75 6.2 에뮬레이터툴바 76 6.3 줌모드사용하기 78 6.4 에뮬레이터창의크기조정 78 6.5 확장제어옵션 78 6.6 드래그 -드롭 81 6.7 모의지문구성하기 82 6.8 멀티코어지원 84 6.9 요약 85 실제안드로이드장치에서애플리케이션테스트하기 _ 86 7.1 ADB 개요 86 7.2 안드로이드장치에서 ADB 활성화하기 87 7.3 adb 연결테스트하기 93 7.4 안드로이드스튜디오에서장치확인하기 94 7.5 요약 97 vi 차례
CHAPTER 8 CHAPTER 9 CHAPTER 10 CHAPTER 11 안드로이드스튜디오코드편집기 _ 98 8.1 안드로이드스튜디오코드편집기 98 8.2 편집기창나누기 101 8.3 코드자동완성 102 8.4 문장자동완성 104 8.5 매개변수정보 104 8.6 코드생성 104 8.7 코드접어감추기 106 8.8 빠른문서검색 107 8.9 소스코드형식변환 108 8.10 샘플코드찾아보기 109 8.11 요약 110 안드로이드아키텍처개요 _ 111 9.1 안드로이드소프트웨어스택 111 9.2 리눅스커널 112 9.3 안드로이드런타임 ART 113 9.4 안드로이드라이브러리 113 9.5 애플리케이션프레임워크 115 9.6 애플리케이션 116 9.7 요약 116 액티비티와인텐트개요 _ 117 10.1 안드로이드액티비티 117 10.2 안드로이드인텐트 118 10.3 브로드캐스트인텐트 118 10.4 브로드캐스트수신자 119 10.5 안드로이드서비스 119 10.6 콘텐트제공자 120 10.7 애플리케이션매니페스트 120 10.8 애플리케이션리소스 120 10.9 애플리케이션컨텍스트 121 10.10 요약 121 안드로이드애플리케이션과액티비티생명주기 _ 122 11.1 안드로이드애플리케이션과리소스관리 122 11.2 안드로이드프로세스상태 123 11.3 액티비티생명주기 124 11.4 액티비티스택 125 11.5 액티비티상태 126 11.6 구성변경 126 11.7 요약 127 차례 vii
CHAPTER 12 CHAPTER 13 CHAPTER 14 CHAPTER 15 CHAPTER 16 액티비티상태변화처리하기 _ 128 12.1 Activity 클래스 128 12.2 동적상태 vs. 영속적상태 132 12.3 안드로이드액티비티생명주기메서드 133 12.4 액티비티생애 135 12.5 액티비티가다시시작되지않게하기 136 12.6 요약 137 액티비티상태변화예제 _ 138 13.1 상태변화예제프로젝트생성하기 138 13.2 사용자인터페이스디자인하기 139 13.3 액티비티생명주기메서드오버라이딩 141 13.4 로그캣패널의메시지필터링하기 144 13.5 애플리케이션실행하기 146 13.6 액티비티로실험하기 147 13.7 요약 149 액티비티상태를저장하고복원하기 _ 150 14.1 동적상태저장 150 14.2 사용자인터페이스상태의자동저장과복원 151 14.3 Bundle 클래스 152 14.4 상태데이터저장하기 153 14.5 상태데이터복원하기 156 14.6 애플리케이션테스트하기 156 14.7 요약 156 안드로이드뷰, 뷰그룹, 레이아웃 _ 158 15.1 서로다른안드로이드장치를위한디자인 158 15.2 뷰와뷰그룹 159 15.3 안드로이드레이아웃매니저 159 15.4 뷰계층구조 161 15.5 사용자인터페이스생성 163 15.6 요약 163 안드로이드스튜디오레이아웃편집기살펴보기 _ 164 16.1 Basic vs. Empty 액티비티템플릿 164 16.2 안드로이드스튜디오레이아웃편집기 167 16.3 디자인모드 167 16.4 팔레트 169 16.5 레이아웃의확대 / 축소보기 170 16.6 디자인뷰와청사진뷰 170 16.7 텍스트모드 171 viii 차례
16.8 속성설정하기 173 16.9 즐겨사용하는속성구성하기 174 16.10 커스텀장치정의생성하기 175 16.11 현재장치변경하기 176 16.12 요약 176 CHAPTER 17 CHAPTER 18 CHAPTER 19 안드로이드 ConstraintLayout 개요 _ 177 17.1 ConstraintLayout 의핵심요소 177 17.2 기준선정렬 182 17.3 지시선사용하기 183 17.4 위젯크기구성하기 183 17.5 비율 183 17.6 ConstraintLayout 의장점 184 17.7 ConstraintLayout 의가용성 184 17.8 요약 184 안드로이드스튜디오에서 ConstraintLayout 사용하기 _ 185 18.1 디자인뷰와레이아웃뷰 185 18.2 자동연결 187 18.3 제약추론 188 18.4 수동연결 188 18.5 제약삭제하기 189 18.6 제약바이어스조정하기 190 18.7 ConstraintLayout 마진이해하기 190 18.8 상대제약과바이어스의중요성 192 18.9 위젯의크기구성하기 194 18.10 지시선추가하기 195 18.11 위젯의그룹정렬 197 18.12 다른타입의레이아웃을 ConstraintLayout 으로변환하기 198 18.13 요약 198 안드로이드스튜디오에서 ConstraintLayout 체인과비율사용하기 _ 199 19.1 체인생성하기 199 19.2 체인스타일변경하기 202 19.3 Spread inside 체인스타일 203 19.4 Packed 체인스타일 203 19.5 바이어스를사용한 Packed 체인스타일 204 19.6 Weighted 체인 204 19.7 비율사용하기 206 19.8 요약 208 차례 ix
CHAPTER 20 CHAPTER 21 CHAPTER 22 CHAPTER 23 CHAPTER 24 ConstraintLayout 예제프로젝트 _ 209 20.1 ConstraintLayout 예제프로젝트생성하기 209 20.2 새로운액티비티생성하기 210 20.3 자동연결설정과이미지파일추가하기 212 20.4 위젯을사용자인터페이스에추가하기 212 20.5 제약추가하기 215 20.6 레이아웃테스트하기 217 20.7 레이아웃검사기사용하기 218 20.8 계층구조뷰어사용하기 219 20.9 요약 223 직접 XML 레이아웃작성하기 _ 224 21.1 직접 XML 레이아웃생성하기 224 21.2 XML 직접작성 vs. 레이아웃편집기의디자인모드사용 228 21.3 요약 229 ConstraintSet 으로 ConstraintLayout 관리하기 _ 230 22.1 자바코드 vs. XML 레이아웃파일 230 22.2 뷰생성하기 231 22.3 뷰속성 232 22.4 ConstraintSet 232 22.5 요약 237 안드로이드 ConstraintSet 예제프로젝트 _ 238 23.1 안드로이드스튜디오로예제프로젝트생성하기 238 23.2 액티비티에뷰추가하기 239 23.3 뷰속성설정하기 240 23.4 뷰 ID 생성하고사용하기 241 23.5 제약설정구성하기 242 23.6 EditText 뷰를추가하기 243 23.7 dp를 px로변환하기 245 23.8 요약 246 안드로이드이벤트처리개요 _ 247 24.1 안드로이드이벤트이해하기 247 24.2 android:onclick 리소스사용하기 248 24.3 이벤트리스너와콜백메서드 249 24.4 이벤트처리예제 250 24.5 사용자인터페이스디자인하기 250 24.6 이벤트리스너와콜백메서드 252 24.7 이벤트소비하기 253 24.8 요약 255 x 차례
CHAPTER 25 CHAPTER 26 CHAPTER 27 CHAPTER 28 안드로이드스튜디오의 Instant Run 사용하기 _ 257 25.1 Instant Run 개요 257 25.2 Instant Run의 Swap 레벨이해하기 258 25.3 Instant Run의활성화와비활성화 258 25.4 Instant Run 사용하기 259 25.5 Instant Run 예제프로젝트 260 25.6 Instant Run의 Hot swap 수행시키기 260 25.7 Instant Run의 Warm swap 수행시키기 261 25.8 Instant Run의 Cold swap 수행시키기 261 25.9 Run 버튼 262 25.10 요약 262 터치와다중터치이벤트처리하기 _ 263 26.1 터치이벤트처리하기 263 26.2 MotionEvent 객체 264 26.3 터치액션이해하기 264 26.4 다중터치처리하기 265 26.5 다중터치애플리케이션생성하기 265 26.6 액티비티사용자인터페이스디자인하기 266 26.7 터치이벤트리스너구현하기 267 26.8 애플리케이션실행시키기 270 26.9 요약 271 안드로이드제스처감지클래스로일반제스처처리하기 _ 272 27.1 일반제스처감지와처리하기 273 27.2 제스처처리프로젝트생성하기 274 27.3 리스너클래스구현하기 274 27.4 GestureDetector 인스턴스생성하기 277 27.5 ontouchevent( ) 메서드구현하기 278 27.6 애플리케이션테스트하기 278 27.7 요약 279 커스텀제스처와핀치인식구현하기 _ 280 28.1 안드로이드제스처빌더애플리케이션 280 28.2 GestureOverlayView 클래스 281 28.3 제스처감지하기 281 28.4 제스처확인하기 281 28.5 제스처빌더애플리케이션의빌드와실행 281 28.6 제스처파일생성하기 282 28.7 SD 카드에서제스처파일추출하기 283 28.8 예제프로젝트생성하기 285 28.9 제스처파일을프로젝트에추가하기 285 28.10 사용자인터페이스디자인하기 285 차례 xi
28.11 제스처파일로드하기 286 28.12 이벤트리스너등록하기 287 28.13 ongestureperformed 메서드구현하기 288 28.14 애플리케이션테스트하기 289 28.15 GestureOverlayView 구성하기 289 28.16 제스처가로채기 290 28.17 핀치제스처처리하기 290 28.18 핀치제스처예제프로젝트 291 28.19 요약 294 CHAPTER 29 CHAPTER 30 CHAPTER 31 안드로이드프래그먼트개요 _ 295 29.1 프래그먼트란? 295 29.2 프래그먼트생성하기 296 29.3 레이아웃 XML 파일을사용하여프래그먼트를액티비티에추가하기 297 29.4 코드에서프래그먼트를추가하고관리하기 299 29.5 프래그먼트이벤트처리하기 301 29.6 프래그먼트간의통신구현하기 302 29.7 요약 304 안드로이드스튜디오에서프래그먼트사용하기 예제프로젝트 _ 305 30.1 예제프래그먼트애플리케이션개요 305 30.2 예제프로젝트생성하기 306 30.3 첫번째프래그먼트레이아웃생성하기 306 30.4 첫번째프래그먼트클래스생성하기 308 30.5 두번째프래그먼트레이아웃생성하기 310 30.6 프래그먼트를액티비티에추가하기 312 30.7 ToolbarFragment가액티비티와통신하게만들기 315 30.8 액티비티에서 TextFragment로통신하기 320 30.9 애플리케이션테스트하기 321 30.10 요약 322 오버플로메뉴생성과관리 _ 323 31.1 오버플로메뉴 323 31.2 오버플로메뉴생성하기 324 31.3 오버플로메뉴보여주기 325 31.4 메뉴항목선택에응답하기 326 31.5 체크가능한항목그룹생성하기 326 31.6 안드로이드스튜디오메뉴편집기 328 31.7 예제프로젝트생성하기 329 31.8 메뉴항목변경하기 329 31.9 onoptionsitemselected( ) 메서드변경하기 332 31.10 애플리케이션테스트하기 333 31.11 요약 334 xii 차례
CHAPTER 32 CHAPTER 33 CHAPTER 34 CHAPTER 35 안드로이드전환프레임워크 _ 335 32.1 안드로이드전환과장면 336 32.2 전환에인터폴레이터사용하기 337 32.3 장면전환사용하기 338 32.4 코드의커스텀전환과 TransitionSet 339 32.5 XML의커스텀전환과 TransitionSet 341 32.6 인터폴레이터사용하기 342 32.7 커스텀인터폴레이터생성하기 345 32.8 begindelayedtransition 메서드사용하기 346 32.9 요약 346 begindelayedtransition 을사용한안드로이드전환 _ 348 33.1 안드로이드스튜디오 TransitionDemo 프로젝트생성하기 348 33.2 프로젝트파일준비하기 349 33.3 begindelayedtransition 애니메이션구현하기 349 33.4 우리입맛에맞는전환만들기 352 33.5 요약 354 안드로이드장면전환구현하기 _ 355 34.1 장면전환프로젝트개요 355 34.2 안드로이드스튜디오 SceneTransitions 프로젝트생성하기 355 34.3 루트컨테이너를확인하고준비하기 356 34.4 첫번째장면디자인하기 356 34.5 두번째장면디자인하기 358 34.6 첫번째장면보여주기 359 34.7 두번째장면로드하기 360 34.8 전환구현하기 360 34.9 전환파일추가하기 361 34.10 전환세트의로딩과사용 362 34.11 부가적인전환구성하기 363 34.12 요약 364 플로팅액션버튼과스낵바사용하기 _ 365 35.1 머티리얼디자인 365 35.2 디자인라이브러리 366 35.3 플로팅액션버튼 (FAB) 366 35.4 스낵바 367 35.5 예제프로젝트생성하기 368 35.6 프로젝트살펴보기 368 35.7 플로팅액션버튼변경하기 370 35.8 ListView를콘텐트레이아웃에추가하기 373 35.9 ListView에항목추가하기 373 35.10 액션을스낵바에추가하기 376 35.11 요약 378 차례 xiii
CHAPTER 36 CHAPTER 37 CHAPTER 38 CHAPTER 39 탭인터페이스생성하기 _ 379 36.1 ViewPager 개요 379 36.2 TabLayout 컴포넌트개요 380 36.3 TabLayoutDemo 프로젝트생성하기 380 36.4 첫번째프래그먼트생성하기 381 36.5 프래그먼트복제하기 382 36.6 TabLayout 과 ViewPager 추가하기 384 36.7 Pager 어댑터생성하기 385 36.8 초기화작업하기 386 36.9 애플리케이션테스트하기 389 36.10 TabLayout 커스터마이징 390 36.11 아이콘탭항목보여주기 391 36.12 요약 392 RecyclerView 와 CardView 사용하기 _ 393 37.1 RecyclerView 개요 393 37.2 CardView 개요 396 37.3 라이브러리를프로젝트에추가하기 398 37.4 요약 398 RecyclerView 와 CardView 예제프로젝트 _ 399 38.1 CardDemo 프로젝트생성하기 399 38.2 플로팅액션버튼삭제하기 400 38.3 RecyclerView와 CardView 라이브러리추가하기 400 38.4 CardView 레이아웃디자인하기 401 38.5 RecyclerView 추가하기 402 38.6 RecyclerView 어댑터생성하기 403 38.7 이미지파일추가하기 406 38.8 RecyclerView 컴포넌트초기화하기 407 38.9 애플리케이션테스트하기 408 38.10 카드선택에응답하기 408 38.11 요약 410 앱바와컬랩싱툴바레이아웃사용하기 _ 411 39.1 AppBar 개요 411 39.2 예제프로젝트 412 39.3 RecyclerView와 Toolbar 연동시키기 413 39.4 컬랩싱툴바레이아웃개요 415 39.5 제목과스크림색상변경하기 419 39.6 요약 420 xiv 차례
CHAPTER 40 CHAPTER 41 CHAPTER 42 CHAPTER 43 내비게이션드로어구현하기 _ 421 40.1 내비게이션드로어개요 421 40.2 드로어를열거나닫기 423 40.3 드로어항목선택에응답하기 424 40.4 내비게이션드로어액티비티템플릿사용하기 425 40.5 내비게이션드로어템플릿으로프로젝트생성하기 425 40.6 템플릿레이아웃리소스파일 426 40.7 헤더색상리소스파일 426 40.8 템플릿메뉴리소스파일 427 40.9 템플릿코드 427 40.10 앱실행하기 428 40.11 요약 429 안드로이드스튜디오마스터 / 디테일플로 _ 430 41.1 마스터 / 디테일플로 430 41.2 마스터 / 디테일플로액티비티생성하기 432 41.3 마스터 / 디테일플로템플릿살펴보기 434 41.4 마스터 / 디테일플로템플릿변경하기 436 41.5 콘텐트모델변경하기 436 41.6 디테일패널변경하기 438 41.7 WebsiteDetailFragment 클래스변경하기 439 41.8 WebsiteListActivity 클래스수정하기 441 41.9 매니페스트퍼미션추가하기 441 41.10 애플리케이션실행하기 442 41.11 요약 443 안드로이드인텐트개요 _ 444 42.1 인텐트개요 444 42.2 명시적인텐트 445 42.3 액티비티에서데이터반환하기 447 42.4 암시적인텐트 448 42.5 인텐트필터사용하기 448 42.6 인텐트사용가능여부확인하기 449 42.7 요약 450 명시적인텐트예제프로젝트 _ 451 43.1 예제프로젝트생성하기 451 43.2 ActivityA의사용자인터페이스디자인하기 452 43.3 두번째액티비티클래스생성하기 453 43.4 ActivityB 의사용자인터페이스레이아웃디자인하기 454 43.5 애플리케이션의매니페스트파일살펴보기 456 43.6 인텐트생성하기 457 43.7 인텐트데이터추출하기 458 차례 xv
43.8 서브액티비티로 ActivityB 론칭하기 459 43.9 서브액티비티에서데이터반환하기 460 43.10 애플리케이션테스트하기 461 43.11 요약 462 CHAPTER 44 CHAPTER 45 CHAPTER 46 암시적인텐트예제프로젝트 _ 463 44.1 암시적인텐트예제프로젝트생성하기 463 44.2 사용자인터페이스디자인하기 464 44.3 암시적인텐트생성하기 465 44.4 암시적인텐트로론칭되는액티비티생성하기 466 44.5 사용자인터페이스에웹뷰추가하기 466 44.6 인텐트 URL 얻기 467 44.7 MyWebView 프로젝트의매니페스트파일변경하기 468 44.8 MyWebView 패키지를장치에설치하기 470 44.9 애플리케이션테스트하기 471 44.10 요약 473 브로드캐스트인텐트와브로드캐스트수신자 _ 474 45.1 브로드캐스트인텐트개요 474 45.2 브로드캐스트수신자개요 475 45.3 브로드캐스트수신자로부터결과데이터받기 478 45.4 스티키브로드캐스트인텐트 478 45.5 브로드캐스트인텐트예제프로젝트 478 45.6 예제애플리케이션생성하기 479 45.7 브로드캐스트인텐트를생성하고전송하기 479 45.8 브로드캐스트수신자생성하기 480 45.9 매니페스트파일에브로드캐스트수신자구성하기 482 45.10 브로드캐스트애플리케이션테스트하기 483 45.11 시스템브로드캐스트인텐트리스닝하기 484 45.12 요약 487 스레드와스레드핸들러 _ 488 46.1 스레드개요 488 46.2 애플리케이션의메인스레드 488 46.3 스레드핸들러 489 46.4 기본적인스레드예제프로젝트 489 46.5 새로운스레드생성하기 492 46.6 스레드핸들러구현하기 493 46.7 핸들러에게메시지전달하기 495 46.8 요약 497 xvi 차례
CHAPTER 47 CHAPTER 48 CHAPTER 49 CHAPTER 50 스타트서비스와바운드서비스개요 _ 499 47.1 스타트서비스 499 47.2 인텐트서비스 500 47.3 바운드서비스 501 47.4 서비스생명주기 502 47.5 소멸된서비스재시작옵션제어하기 502 47.6 매니페스트파일에서비스선언하기 503 47.7 시스템구동시서비스시작시키기 504 47.8 요약 505 스타트서비스구현예제프로젝트 _ 506 48.1 예제프로젝트생성하기 506 48.2 Service 클래스생성하기 507 48.3 서비스를매니페스트파일에추가하기 509 48.4 서비스시작시키기 509 48.5 인텐트서비스테스트하기 510 48.6 Service 클래스사용하기 511 48.7 새로운서비스생성하기 511 48.8 사용자인터페이스변경하기 513 48.9 애플리케이션실행하기 514 48.10 서비스를처리하는새로운스레드생성하기 515 48.11 요약 517 로컬바운드서비스예제프로젝트 _ 518 49.1 바운드서비스이해하기 518 49.2 바운드서비스상호작용옵션 519 49.3 로컬바운드서비스예제프로젝트 519 49.4 바운드서비스를프로젝트에추가하기 520 49.5 Binder 구현하기 520 49.6 클라이언트를서비스에바인딩하기 523 49.7 예제프로젝트마무리하기 525 49.8 애플리케이션테스트하기 527 49.9 요약 528 원격바운드서비스예제프로젝트 _ 529 50.1 클라이언트에서원격서비스로통신하기 529 50.2 예제애플리케이션생성하기 530 50.3 사용자인터페이스디자인하기 530 50.4 원격바운드서비스구현하기 530 50.5 원격서비스를매니페스트파일에구성하기 532 50.6 원격서비스를론칭하고바인딩하기 533 50.7 원격서비스에메시지전송하기 534 50.8 요약 536 차례 xvii
CHAPTER 51 CHAPTER 52 CHAPTER 53 CHAPTER 54 안드로이드 7 의알림개요 _ 537 51.1 알림개요 537 51.2 NotifyDemo 프로젝트생성하기 539 51.3 사용자인터페이스디자인하기 539 51.4 두번째액티비티생성하기 540 51.5 알림을생성하고전달하기 541 51.6 알림에서액티비티를시작시키기 543 51.7 알림에액션추가하기 544 51.8 알림에소리추가하기 545 51.9 알림메시지묶기 546 51.10 요약 549 안드로이드 7 알림의직접응답구현 _ 550 52.1 DirectReply 프로젝트생성하기 550 52.2 사용자인터페이스디자인하기 551 52.3 RemoteInput 객체생성하기 551 52.4 PendingIntent 객체생성하기 553 52.5 응답액션생성하기 553 52.6 직접응답입력데이터수신하기 556 52.7 알림변경하기 557 52.8 요약 558 안드로이드스튜디오에서 Firebase 사용하기 _ 559 53.1 Firebase란? 559 53.2 Firebase에서명하기 560 53.3 FirebaseNotify 프로젝트생성하기 561 53.4 사용자인터페이스구성하기 561 53.5 프로젝트를 Firebase에연결하기 561 53.6 새로운 Firebase 프로젝트생성하기 563 53.7 google-services.json 파일 563 53.8 Firebase 라이브러리추가하기 564 53.9 요약 566 Firebase 원격알림사용하기 _ 567 54.1 Firebase 알림전송하기 567 54.2 알림메시지수신하기 570 54.3 알림에맞춤데이터포함시키기 570 54.4 포그라운드앱의알림처리하기 572 54.5 요약 574 xviii 차례
CHAPTER 55 CHAPTER 56 CHAPTER 57 CHAPTER 58 안드로이드 7 의다중창지원개요 _ 575 55.1 분할화면과자유형식및 PIP 모드 575 55.2 다중창모드로전환하기 577 55.3 자유형식모드의지원여부확인하기 579 55.4 다중창지원을앱에서활성화하기 580 55.5 다중창관련속성지정하기 580 55.6 액티비티에서다중창모드인지검사하기 581 55.7 다중창관련통지받기 582 55.8 다중창모드에서액티비티를시작시키기 582 55.9 자유형식모드로실행되는액티비티의크기와위치구성하기 583 55.10 요약 584 다중창예제프로젝트 _ 585 56.1 다중창프로젝트생성하기 585 56.2 FirstActivity 의사용자인터페이스디자인하기 585 56.3 두번째액티비티추가하기 586 56.4 두번째액티비티시작시키기 587 56.5 다중창모드활성화하기 588 56.6 다중창지원테스트하기 589 56.7 두번째액티비티를다른창에서시작시키기 590 56.8 자유형식창의위치와크기변경하기 591 56.9 요약 592 안드로이드 SQLite 데이터베이스개요 _ 593 57.1 데이터베이스테이블이해하기 593 57.2 데이터베이스스키마개요 594 57.3 열과데이터타입 594 57.4 데이터베이스행 594 57.5 기본키개요 595 57.6 SQLite란? 595 57.7 SQL 596 57.8 AVD에서 SQLite 사용해보기 596 57.9 안드로이드 SQLite 자바클래스 600 57.10 요약 602 TableLayout 과 TableRow 개요 _ 603 58.1 TableLayout 과 TableRow 603 58.2 데이터베이스프로젝트생성하기 605 58.3 사용자인터페이스에 TableLayout 추가하기 605 58.4 TableRow 구성하기 606 58.5 버튼을레이아웃에추가하기 608 58.6 레이아웃마진조정하기 609 58.7 요약 610 차례 xix
CHAPTER 59 CHAPTER 60 CHAPTER 61 CHAPTER 62 안드로이드 SQLite 데이터베이스예제프로젝트 _ 611 59.1 데이터베이스예제개요 611 59.2 데이터모델생성하기 612 59.3 데이터핸들러구현하기 613 59.4 액티비티이벤트메서드구현하기 618 59.5 애플리케이션테스트하기 620 59.6 요약 621 콘텐트제공자이해하기 _ 622 60.1 콘텐트제공자란? 622 60.2 콘텐트제공자 623 60.3 콘텐트 URI 624 60.4 콘텐트리졸버 625 60.5 <provider> 매니페스트요소 625 60.6 요약 626 콘텐트제공자구현하기 _ 627 61.1 Database 프로젝트활용하기 627 61.2 콘텐트제공자패키지추가하기 628 61.3 콘텐트제공자클래스생성하기 628 61.4 Authority와콘텐트 URI 구성하기 630 61.5 콘텐트제공자에 UriMatcher 구현하기 631 61.6 콘텐트제공자의 oncreate( ) 메서드구현하기 632 61.7 콘텐트제공자의 insert( ) 메서드구현하기 633 61.8 콘텐트제공자의 query( ) 메서드구현하기 634 61.9 콘텐트제공자의 update( ) 메서드구현하기 636 61.10 콘텐트제공자의 delete( ) 메서드구현하기 637 61.11 매니페스트파일에콘텐트제공자선언하기 638 61.12 데이터베이스핸들러변경하기 639 61.13 요약 642 구글클라우드스토리지액세스하기 _ 643 62.1 스토리지액세스프레임워크 643 62.2 스토리지액세스프레임워크사용하기 645 62.3 피커의파일내역선별하기 645 62.4 인텐트결과처리하기 647 62.5 파일의내용읽기 648 62.6 파일에내용쓰기 649 62.7 파일삭제하기 649 62.8 파일의지속적인액세스얻기 650 62.9 요약 650 xx 차례
CHAPTER 63 CHAPTER 64 CHAPTER 65 CHAPTER 66 안드로이드스토리지액세스프레임워크예제프로젝트 _ 652 63.1 스토리지액세스프레임워크예제프로젝트개요 652 63.2 스토리지액세스프레임워크예제프로젝트생성 653 63.3 사용자인터페이스디자인하기 653 63.4 요청코드선언하기 654 63.5 새로운스토리지파일생성하기 655 63.6 onactivityresult( ) 메서드 657 63.7 스토리지파일에데이터저장하기 659 63.8 스토리지파일을열고읽기 661 63.9 스토리지액세스애플리케이션테스트하기 664 63.10 요약 665 비디오재생구현하기 _ 666 64.1 안드로이드 VideoView 클래스개요 666 64.2 안드로이드 MediaController 클래스개요 667 64.3 비디오재생테스트관련사항 668 64.4 비디오재생예제프로젝트생성하기 668 64.5 VideoPlayer 애플리케이션의레이아웃디자인하기 669 64.6 VideoView 구성하기 670 64.7 인터넷퍼미션추가하기 670 64.8 MediaController를 VideoView에추가하기 672 64.9 onpreparedlistener 설정하기 673 64.10 요약 674 카메라인텐트를사용한비디오녹화와이미지캡처 _ 675 65.1 카메라지원여부확인하기 675 65.2 비디오캡처인텐트호출하기 676 65.3 이미지캡처인텐트호출하기 677 65.4 안드로이드스튜디오비디오녹화프로젝트생성하기 678 65.5 사용자인터페이스레이아웃디자인하기 678 65.6 카메라확인하기 679 65.7 비디오캡처인텐트론칭하기 680 65.8 인텐트의반환결과처리하기 681 65.9 애플리케이션테스트하기 682 65.10 요약 682 런타임퍼미션요청하기 _ 683 66.1 보통과위험퍼미션이해하기 683 66.2 퍼미션예제프로젝트생성하기 685 66.3 퍼미션확인하기 685 66.4 런타임시에퍼미션요청하기 687 66.5 퍼미션요청이유제공하기 689 66.6 퍼미션앱테스트하기 691 66.7 요약 692 차례 xxi
CHAPTER 67 CHAPTER 68 CHAPTER 69 CHAPTER 70 안드로이드오디오녹음과재생하기 _ 693 67.1 오디오재생하기 693 67.2 MediaRecorder 클래스를사용해서오디오녹음하기 694 67.3 예제프로젝트개요 696 67.4 AudioApp 프로젝트생성하기 696 67.5 사용자인터페이스디자인하기 697 67.6 마이크확인하기 698 67.7 액티비티초기화하기 699 67.8 recordaudio( ) 메서드구현하기 700 67.9 stopaudio( ) 메서드구현하기 701 67.10 playaudio( ) 메서드구현하기 702 67.11 매니페스트파일에퍼미션구성하기 702 67.12 애플리케이션테스트하기 706 67.13 요약 706 구글맵 API 사용하기 _ 707 68.1 구글맵안드로이드 API의구성요소 707 68.2 구글맵프로젝트생성하기 709 68.3 개발자서명얻기 709 68.4 애플리케이션테스트하기 712 68.5 지오코딩과역-지오코딩이해하기 713 68.6 지도를애플리케이션에추가하기 715 68.7 현재위치퍼미션요청하기 716 68.8 사용자의현재위치보여주기 718 68.9 지도타입변경하기 719 68.10 맵컨트롤을사용자에게보여주기 720 68.11 지도제스처처리하기 721 68.12 지도표식생성하기 723 68.13 맵카메라제어하기 724 68.14 요약 726 안드로이드인쇄프레임워크사용하기 _ 727 69.1 안드로이드인쇄아키텍처 727 69.2 인쇄서비스플러그인 728 69.3 구글클라우드인쇄 728 69.4 구글드라이브로인쇄하기 729 69.5 PDF로저장하기 729 69.6 안드로이드장치에서인쇄하기 730 69.7 안드로이드애플리케이션에포함되는인쇄지원옵션 732 69.8 요약 737 HTML 과웹콘텐트인쇄예제프로젝트 _ 738 70.1 HTML 인쇄예제애플리케이션생성하기 738 70.2 동적 HTML 콘텐트인쇄하기 739 xxii 차례
70.3 기존웹페이지인쇄예제애플리케이션생성하기 742 70.4 플로팅액션버튼삭제하기 743 70.5 사용자인터페이스레이아웃디자인하기 743 70.6 웹페이지를 WebView에로드하기 745 70.7 인쇄메뉴옵션추가하기 746 70.8 요약 749 CHAPTER 71 CHAPTER 72 CHAPTER 73 안드로이드커스텀문서인쇄 _ 750 71.1 안드로이드커스텀문서인쇄개요 750 71.2 커스텀문서인쇄프로젝트준비하기 752 71.3 커스텀인쇄어댑터생성하기 753 71.4 onlayout( ) 콜백메서드구현하기 754 71.5 onwrite( ) 콜백메서드구현하기 758 71.6 페이지가인쇄범위에있는지확인하기 761 71.7 페이지캔버스에콘텐트그리기 762 71.8 인쇄작업시작시키기 765 71.9 애플리케이션테스트하기 766 71.10 요약 767 안드로이드지문인증구현하기 _ 768 72.1 지문인증개요 768 72.2 지문인증프로젝트생성하기 769 72.3 장치의지문인증구성하기 769 72.4 지문퍼미션을매니페스트파일에추가하기 770 72.5 지문아이콘다운로드하기 771 72.6 사용자인터페이스디자인하기 772 72.7 KeyguardManager와 FingerprintManager 사용하기 773 72.8 장치의보안설정확인하기 774 72.9 안드로이드 Keystore와 KeyGenerator 사용하기 775 72.10 키생성하기 777 72.11 Cipher 초기화하기 779 72.12 CryptoObject 인스턴스생성하기 781 72.13 지문인증처리클래스구현하기 782 72.14 프로젝트테스트하기 785 72.15 요약 786 서로다른안드로이드장치와화면처리하기 _ 787 73.1 서로다른장치화면처리하기 787 73.2 화면크기에맞는레이아웃생성하기 788 73.3 안드로이드스튜디오에서다양한크기의레이아웃생성하기 789 73.4 서로다른이미지제공하기 790 73.5 하드웨어지원여부확인하기 791 73.6 특정장치에맞는애플리케이션바이너리제공하기 792 73.7 요약 792 차례 xxiii
CHAPTER 74 CHAPTER 75 CHAPTER 76 안드로이드애플리케이션릴리스하기 _ 793 74.1 릴리스준비절차 793 74.2 빌드변이변경하기 794 74.3 ProGuard 활성화하기 795 74.4 키스토어파일생성하기 795 74.5 개인키생성하기 796 74.6 애플리케이션 APK 파일생성하기 797 74.7 구글플레이개발자콘솔계정등록하기 799 74.8 새로운 APK 버전을구글플레이개발자콘솔에업로드하기 799 74.9 APK 파일분석하기 801 74.10 요약 803 구글플레이인앱결제를애플리케이션에통합하기 _ 804 75.1 구글플레이결제라이브러리설치하기 804 75.2 인앱결제예제프로젝트생성하기 805 75.3 결제퍼미션을매니페스트파일에추가하기 806 75.4 IInAppBillingService.aidl 파일을프로젝트에추가하기 807 75.5 유틸리티클래스를프로젝트에추가하기 808 75.6 사용자인터페이스디자인하기 810 75.7 Click Me! 버튼구현하기 811 75.8 구글플레이개발자콘솔과구글계정 812 75.9 애플리케이션의공개인증키받기 812 75.10 애플리케이션에서구글플레이결제설정하기 814 75.11 구글플레이인앱결제구입을초기설정하기 815 75.12 onactivityresult 메서드구현하기 816 75.13 구입종료리스너구현하기 817 75.14 구입제품소비하기 818 75.15 IabHelper 인스턴스해제하기 819 75.16 Security.java 파일변경하기 820 75.17 인앱결제애플리케이션테스트하기 821 75.18 릴리스용 APK 빌드하기 822 75.19 새로운인앱제품생성하기 823 75.20 알파배포채널로애플리케이션제출하기 824 75.21 인앱결제테스트계정추가하기 824 75.22 그룹테스트구성하기 826 75.23 인앱구입의문제해결하기 826 75.24 요약 828 안드로이드스튜디오의그래들개요 _ 829 76.1 그래들개요 829 76.2 그래들과안드로이드스튜디오 830 76.3 최상위수준의그래들빌드파일 832 76.4 모듈수준의그래들빌드파일들 833 76.5 빌드파일에서명설정구성하기 837 76.6 명령행에서그래들작업실행하기 838 76.7 요약 840 xxiv 차례
CHAPTER 77 안드로이드스튜디오그래들빌드예제프로젝트 _ 841 77.1 빌드변이예제프로젝트생성하기 842 77.2 빌드플레이버를모듈빌드파일에추가하기 842 77.3 플레이버를프로젝트구조에추가하기 845 77.4 리소스파일을플레이버에추가하기 847 77.5 빌드플레이버테스트하기 848 77.6 빌드변이와클래스파일 849 77.7 빌드플레이버에패키지추가하기 849 77.8 각플레이버의액티비티클래스변경하기 850 77.9 요약 851 853 부록 A, B 는독자들의이해를위해옮긴이가작성한특별부록입니다. 아래의사이트에서예제프로젝트파일과함께무료로다운로드받으실수있습니다. URL https://github.com/jpub/androidstudio3 APPENDIX A 코틀린핵심파악하기 : 개요와실습환경구축 A.1 코틀린언어개요 A.2 자바 JDK 설치하기 A.3 코틀린컴파일러설치하기 A.4 코틀린으로네이티브애플리케이션작성과실행하기 A.5 요약 APPENDIX B 코틀린핵심파악하기 : 구성요소와문법 B.1 코틀린프로그램구조 B.2 코틀린변수 B.3 코틀린의타입 B.4 연산자와연산자오버로딩 B.5 Null 타입처리메커니즘 B.6 코드실행제어 B.7 함수 B.8 클래스와인터페이스 B.9 람다식 B.10 예외처리 B.11 package와 import 차례 xxv
정성과최선을다했습니다. 한마디로요약해서독자여러분께드리고싶은제진심의표현입니다. 용어하나하나, 내용모두에걸쳐심사숙고하였으며, 실습용프로젝트코드의작성및수정과테스트를병행하여이책을완성하였습니다. 이책에서는안드로이드스튜디오를사용해서안드로이드애플리케이션을개발하는데필요한핵심적인내용을알려줍니다. 즉, 안드로이드스튜디오를사용하는데꼭필요한내용은물론이고, 안드로이드애플리케이션개발에반드시알아야할내용도골고루가르쳐줍니다. 그리고이모든것을안드로이드스튜디오의실습프로젝트로구성하여독자여러분이직접만들어체험하면서쉽게배울수있도록구성되었습니다. 또한, 안드로이드프로그래밍기법과안드로이드스튜디오의최신기능을반영하고있습니다. 따라서안드로이드스튜디오를사용해서안드로이드애플리케이션개발을배우고시작하려는분들께적극권하고싶은책입니다. 또한, 안드로이드스튜디오를빠른시간내에파악하고싶은기존개발자분들께도권하고싶습니다. 이책을번역하면서다음과같은부분에중점을두었습니다. 1. 모든내용을안드로이드스튜디오 3 최신버전에맞춰수정하고보충하였습니다. 2. 용어선정에신중을기하고독자여러분의이해를돕는데필요한설명을많이추가하였습니다. 3. 책의각종프로젝트를독자여러분이만들면서실습하는데도움이될수있도록결함을수정하고미비한점을보완하였습니다. xxvi 옮긴이머리말
이책은더욱강력해진안드로이드스튜디오 3를기준으로만든최신안드로이드도서입니다. 독자여러분께도움이될수있는책을만들어야한다는집념이있었기에가능했던것같습니다. 이책을출간하는데아낌없는배려와수고를해주신제이펍출판사의장성두사장님과이민숙과장님께진심으로감사드립니다. 2017년 7월옮긴이 드림 옮긴이머리말 xxvii
C H A P T E R 1 개요 이책은최신버전의안드로이드스튜디오 (Android Studio) 와안드로이드 SDK(Software Development Kit) 를사용해서안드로이드애플리케이션 (application, 줄여서 app) 을개발하는데필요한기법을가르쳐준다. 안드로이드스튜디오는안드로이드애플리케이션을개발할때사용하는통합개발환경 (IDE, Integrated Development Environment) 이다. 우선은안드로이드애플리케이션을개발하고테스트하는환경을구축하는데필요한내용을설명한다. 그리고안드로이드스튜디오의주요기능과사용법을살펴본다. 예를들어, 각종도구창, 코드편집기, 레이아웃편집기와같은것들이다. 또한, 인스턴트런 (Instant Run) 기능과향상된 AVD(Android Virtual Device) 에뮬레이터도살펴본다. 그다음에안드로이드의아키텍처를간략히살펴본후안드로이드스튜디오를사용해서애플리케이션과사용자인터페이스를설계하고만드는방법들을자세히알아볼것이다. 이때데이터베이스, 콘텐트제공자 (content provider), 인텐트 (intent) 와같은여러고급주제들도다룬다. 또한, 터치스크린처리, 제스처인식, 카메라사용, 비디오와오디오의재생과녹화방법도설명한다. 그리고인쇄, 애니메이션화면전환, 클라우드기반파일스토리지도다룬다. 이러한보편적인안드로이드애플리케이션개발기법들외에도이책에서는구글플레이 (Google Play) 와연관된내용들도설명한다. 구글맵 (Google Map) API를사용한지도구현이라든지, 구글플레이개발자콘솔에우리가만든애플리케이션을게시하고인앱결제 (in-app billing) 를하는방법등이다. 1
또한, 애플리케이션프로젝트파일들을구성및관리하고빌드 (build) 하기위해안드로이드스튜디오에서플러그인하여사용하는자동화프로젝트시스템 ( 도구 ) 인그래들 (Gradle) 에대해서도살펴본다. 그리고안드로이드버전 5( 롤리팝 ) 에소개된머티리얼 (material) 디자인의개념과안드로이드버전 6( 마시멜로 ) 에서완벽하게구현된머티리얼사용자인터페이스도설명한다. 즉, 플로팅액션버튼 (floating action button), 스낵바 (Snackbar), 탭인터페이스 (tabbed interface), 카드뷰 (card view), 내비게이션드로어 (navigation drawers), 컬랩싱툴바 (collapsing toolbar) 등이다. 또한, 변경된퍼미션메커니즘과지문인식구현방법도알아본다. 더불어안드로이드스튜디오최신버전에서새롭게변경된레이아웃편집기의기능과사용법을알려주며, 안드로이드버전 7( 누가 ) 에새로추가된 ConstraintLayout 클래스, 직접응답알림 (direct reply notifications), Firebase 서비스, 다중창지원 (multi-window support) 기능의개념과구현방법도배운다. 이책에서는여러분이자바 (Java) 프로그래밍을해본경험이있다고간주하므로자바언어에관한언급은따로하지않을것이다. 그리고윈도우 (Windows) 나맥 (Mac) 또는리눅스 (Linux) 가실행되는컴퓨터가있고안드로이드스튜디오와안드로이드 SDK를다운로드및설치할수있으면시작준비가된것이다. 이책의모든본문과그림및프로젝트코드는안드로이드스튜디오최신버전 (3.0 이상 ) 을사용하여작성되었다. 따라서독자여러분이안드로이드스튜디오를사용한최신안드로이드프로그래밍을배우는데어려움이없을것이다. 1.1 안드로이드스튜디오의장점 안드로이드스튜디오에서는종전의이클립스 IDE보다훨씬강력하고특화된기능을제공한다. 그리고앞으로구글에서는구글클라우드플랫폼 (Google Cloud Platform) 과연계시켜더욱확장된기능을제공할것이다. 중요한것만요약하면다음과같다. 유연성이좋은그래들 (Gradle) 기반의자동화프로젝트빌드시스템을사용한다 ( 이클립스에서는 Ant 사용 ). 하나의프로젝트코드로여러안드로이드장치용애플리케이션을구현할수있다. 이기능은안드로이드웨어 (Android Wear) 에서특히유용하다. 2 CHAPTER 1 개요
구글의각종서비스와다양한장치유형을지원하는각종템플릿들이있어서프로젝트에필요한기본적인코드와파일들을자동으로생성해준다. 그래픽레이아웃편집기의기능이강력하고사용하기쉬워서사용자인터페이스디자인이편리하다. 코드의성능이나버전호환성및기타문제점을잡아내는 Lint의기능이강화되었다. 구글클라우드플랫폼을자체적으로지원하여구글클라우드메시징 / 앱엔진과쉽게통합할수있다. 우리의코드를사전에분석하여완성도를보완해주고리팩토링 (refactoring) 을해주는각종분석도구를지원한다. 1.2 소스코드다운로드하기 이책에나오는각종예제의안드로이드스튜디오프로젝트파일들은다음에서다운로드할수있다. URL https://github.com/jpub/androidstudio3 예제프로젝트코드를안드로이드스튜디오로로드하는절차는다음과같다. 1. Welcome to Android Studio 대화상자에서 Open an existing Android Studio project를선택하거나안드로이드스튜디오메인메뉴의 File Open... 을선택한다. 2. 프로젝트선택대화상자가나오면열려는프로젝트관련파일들이있는서브디렉터리 ( 프로젝트이름과동일함 ) 를선택하고 OK를클릭한다. 3. Sync Android SDKs 대화상자가나오면 OK를클릭한다 ( 열려는프로젝트에지정되어있는안드로이드 SDK 설치디렉터리와현재사용중인컴퓨터의안드로이드 SDK 설치디렉터리가달라서이대화상자가나오는것이다. OK를클릭하면현재사용중인컴퓨터의안드로이드 SDK 설치디렉터리가프로젝트의디폴트로사용된다 ). 4. 만일프로젝트가로드되면서 Android Gradle Plugin Update Required 대화상자가나타날때는반드시 Update 버튼을클릭해야한다 ( 프로젝트에포함되는그래들플러그인의버전이업데이트되어야하기때문이다 ). 5. 프로젝트가로드된후아무창도열려있지않으면 Alt와숫자 1[ 맥 OS X에서는 Cmd와숫자 1] 키를같이눌러프로젝트도구창을연후필요한파일을편집기창으로로드한다. 1.2 소스코드다운로드하기 3
이책의실습프로젝트에서는여러가지의최소 SDK 버전을사용한다. 안드로이드 5.1( 롤리팝, API 22), 안드로이드 6.0( 마시멜로, API 23), 안드로이드 7.x( 누가, API 24/25) 등이다. 그리고애플리케이션으로실행할때는안드로이드 8(API 26) AVD 에뮬레이터와실제장치 ( 스마트폰 ) 를같이사용하였다. 만일다운로드한프로젝트소스를에뮬레이터가아닌각자의스마트폰이나태블릿으로실행하고자할때는그장치의안드로이드버전과같거나또는낮은버전으로최소 SDK 버전을변경해야한다. 이때는프로젝트도구창의 Gradle Scripts build.gradle (Module: app) 파일을더블클릭하여편집기에로드한후, minsdkversion 번호를해당안드로이드버전의 API 레벨번호로수정하고실행하면된다 ( 그림 1-1). 그림 1-1 1.3 단축키와코드표기 이책에서는두개이상의키보드키를누를때 + 기호로나타내었다. 예를들어, Alt 키와 Enter 키를같이누를때는 Alt + Enter로표기하였다. 또한, 단축키는윈도우키 [ 맥 OS X 키 ] 의형태로표시되어있다. 예를들면 Alt + Enter[Option + Enter]. 소스코드의삭제는글자가운데를가로지르는취소선으로표시하였으며, 추가되는코드는진한글씨로나타내었다. 1.4 안드로이드스튜디오최신버전사용하기 이책의모든내용은안드로이드스튜디오 3.0 Canary 8 릴리즈를기준으로작성되었다. 따라서안드로이드스튜디오 3.0 이전버전과는다른부분이있을수있으므로반드시안드로이드스튜디오 3.0 이상으로실습해야한다. 만일이책이출간된후에도안드로이드스튜디오 3.0 공식버전이발표되지않았다면, 다음을방문하여프리뷰버전을다운로드받자. 4 CHAPTER 1 개요
URL https://developer.android.com/studio/preview/index.html 그리고별도의설치없이압축을푼후 \bin 서브디렉터리에있는 studio.exe(32비트 ) 또는 studio64.exe(64비트 ) 를실행하면안드로이드스튜디오를사용할수있다. 단, 안드로이드 SDK 와자바 JDK를설치해야하므로 2장에서설명한대로현재의공식버전도설치하기바란다 ( 안드로이드스튜디오는서로다른버전을설치하고사용해도문제가생기지않는다 ). 1.5 독자 A/S 여러분이만족하는책이되었으면한다. 혹시오류를발견하거나문의사항이있으면 jcspro@ hanafos.com 혹은 readers.jpub@gmail.com 으로메일을보내주기바란다. 1.6 오탈자 이책의내용에오류가없도록최선의노력을했지만, 혹시오탈자가있을지도모르겠다. 그런 경우는제이펍 (www.jpub.kr) 의이책소개페이지에있는정오표코너에서안내하도록하겠다. 1.6 오탈자 5
C H A P T E R 20 ConstraintLayout 예제프로젝트 안드로이드스튜디오레이아웃편집기를사용하면쉽고생산성높은방법으로안드로이드애플리케이션의사용자인터페이스를디자인할수있다. 이번장에서는안드로이드스튜디오레이아웃편집기를사용해서 ConstraintLayout 기반의사용자인터페이스를생성하는방법을알아본다. 또한, 레이아웃검사기와계층구조뷰어도구의사용법도설명한다. 20.1 ConstraintLayout 예제프로젝트생성하기 우선, 새로운안드로이드스튜디오프로젝트를생성하자. 안드로이드스튜디오메인메뉴의 File New New Project... 를선택하거나웰컴스크린에서 Start a new Android Studio project를선택한다. 그러면새프로젝트를생성하는첫번째대화상자가나타날것이다. Application name 필드에는 LayoutSample을입력하고, Company Domain에는 ebookfrenzy. com을입력한후 Next 버튼을누르자. 안드로이드장치선택화면에서는폰과태블릿 (Phone and Tablet) 을선택하고, 최소 SDK는 API 22: Android 5.1 (Lollipop) 을그대로둔다. Next 버튼을누르면액티비티타입을선택하는대화상자가나올것이다. 앞의다른장에서는 Empty Activity와같은템플릿을선택해서프로젝트액티비티를자동생성했었다. 그러나여기서는새로운액티비티와그것의레이아웃리소스파일을직접생성하는방법을배울것이므로 Add No Activity를선택하고 Finish 버튼을눌러서프로젝트를생성한다. 209
20.2 새로운액티비티생성하기 새프로젝트의생성이끝나면안드로이드스튜디오메인창이텅빈공간으로나타날것이다. 다음으로할일은새액티비티를생성하는것이다. 안드로이드애플리케이션을개발할때아무액티비티도없는상태에서새로운액티비티를생성할필요가있는경우가더러있다. 따라서여기서작성하는예제가도움이될것이다. Alt + 1 [ Cmd + 1 ] 단축키를눌러서프로젝트도구창을열자. 프로젝트도구창의각폴더를다음과같이확장시켜서 app java com.ebookfrenzy.layoutsample 패키지를찾자. 그리고패키지이름에서마우스오른쪽버튼을클릭한후 New Activity Empty Activity 를선택한다 ( 그림 20-1). 그림 20-1 새액티비티생성대화상자가나오면 Activity Name에 LayoutSampleActivity 를입력하자. 또한, 자동으로설정된 Layout Name인 activity_layout_sample은그대로두고 Generate Layout File 도체크된상태로둔다. 레이아웃리소스파일은자동생성할필요가있기때문이다. 또한 Backwards Compatibility (AppCompat) 도체크된상태로둔다. 우리앱이구버전의안드로이드에서실행되더라도호환이되도록하기위함이다. 잠깐, 아직 Finish 버튼은누르지말자! 210 CHAPTER 20 ConstraintLayout 예제프로젝트
애플리케이션이장치에서실행되기위해서는론처액티비티 (launcher activity) 라는액티비티를갖고있어야한다. 론처액티비티가없으면애플리케이션이최초론칭될때어떤액티비티를시작시켜야하는지안드로이드운영체제가알수없다. 따라서애플리케이션이시작되지못한다. 여기서는하나의액티비티만갖고있으므로그것을우리애플리케이션의론처액티비티로지정해야한다. 대화상자에서 Launcher Activity 옵션을체크한후 Finish 버튼을누르자. 이제는안드로이드스튜디오가두개의파일을우리프로젝트에추가했을것이다. 액티비티의자바소스코드파일 (LayoutSampleActivity.java) 은 app java com.ebookfrenzy.layoutsample 폴더에있으며, 편집기창에이미로드되었을것이다. 또한, 사용자인터페이스의 XML 레이아웃파일 (activity_layout_sample.xml) 은 app res layout 폴더에생성되었으며, 이것역시편집기창에이미로드되었을것이다. 끝으로, 새로생성된액티비티가 AndroidManifest.xml 파일에추가되어론처액티비티로지정되어있을것이다. 매니페스트파일도프로젝트창에서볼수있다. app manifests 폴더밑에있으며다음의 XML을포함한다. 여기서 <intent-filter> 와 </intent-filter> 태그사이에있는 category 요소에론처액티비티로지정된다. <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ebookfrenzy.layoutsample"> <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundicon="@mipmap/ic_launcher_round" android:supportsrtl="true" android:theme="@style/apptheme"> <activity android:name=".layoutsampleactivity"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> </application> </manifest> 20.2 새로운액티비티생성하기 211
20.3 자동연결설정과이미지파일추가하기 편집기의 activity_layout_sample.xml 레이아웃파일탭을클릭하고편집기창의제일밑에있는 Design 탭을클릭하여디자인모드로변경한다. 그리고컴포넌트트리에서레이아웃 (ConstraintLayout) 을클릭한후만일레이아웃편집기왼쪽위의 Autoconnect 버튼모양이이면클릭하여그림 20-2 처럼로변경한다. 자동연결을비활성화한후나중에우리가직접제약연결을추가하는방법을배우기위해서다. 그림 20-2 여기서는 ImageView 객체를사용해서이미지를보여줄것이다. 따라서프로젝트에이미지파일을추가해야한다. 파일이름은 galaxys6.png 이며, 이책의프로젝트파일을다운로드받으면 Material_Icons 디렉터리밑에있다. 이미지파일을각자컴퓨터운영체제의파일시스템에서찾은후클립보드로복사한다. 그리고프로젝트도구창의 app res drawable에서오른쪽마우스버튼을클릭한후 Paste를선택하고대화상자에서 OK 버튼을누른다. 그림 20-3처럼제대로복사가되었는지확인한다. 그림 20-3 20.4 위젯을사용자인터페이스에추가하기 팔레트의 Images 부류에있는 ImageView 를마우스로끌어서레이아웃의중앙에놓으면 ( 수직과수평의점선이만나는곳이중앙이다 ) Resources 대화상자가나타난다. 제일왼쪽위에 212 CHAPTER 20 ConstraintLayout 예제프로젝트
있는 Drawable 을클릭하고바로오른쪽의 Project 밑에있는 galaxys6 을클릭한다 ( 그림 20-4). 그림 20-4 OK 버튼을누르면이이미지가 ImageView 에지정된다. 그리고부모레이아웃과약간의좌우 여백이생기도록 ImageView 의크기를조정한후마우스로끌어서레이아웃의중앙으로이동 시킨다 (ImageView 의네개꼭지점에나타난작은사각형을마우스로끌면크기를조정할수있다 ). 그림 20-5 20.4 위젯을사용자인터페이스에추가하기 213
팔레트의 Text 부류에있는 TextView를끌어서 ImageView 위쪽에놓는다. 그리고속성창에서 text 속성을 Samsung Galaxy S6 으로변경하고모든속성보기버튼 ( ) 을클릭하여모든속성이나타나게한다. textalignment의오른쪽필드를클릭하여드롭다운에서 center를선택하고 textsize 속성의값을 24sp(dp 아님 ) 로입력한후 TextView가수평으로중앙에오도록조정한다 ( 그림 20-6). 그림 20-6 그다음에세개의버튼을추가하고각버튼의 text 속성값을 Buy Now, Pricing, Details 로 변경한다. 완성된레이아웃은그림 20-7 과같다. 214 CHAPTER 20 ConstraintLayout 예제프로젝트 그림 20-7
현재는각위젯의위치와크기를제어하는데필요한제약이충분하게추가되어있지않다. 따라서이상태로앱을실행한다면모든위젯들이화면의왼쪽위모서리에겹쳐서나타날것이다. 현재상태에서레이아웃편집기툴바의화면방향전환버튼 ( 그림 20-8의화살표로표시됨 ) 을클릭하여가로방향으로화면을회전시키자. 그림 20-8 이그림을보면알수있듯이, 이미지의일부가잘린상태로중앙에도위치하지않으며, 세개 의버튼은화면영역을벗어나서아예보이지도않는다. 화면크기변화에맞춰레이아웃과 위젯을적합하게나타낼제약이지정되지않았기때문이다. 20.5 제약추가하기 장치의방향변경이나서로다른화면크기에적응가능한레이아웃을생성하는핵심요소가제약이다. 레이아웃을다시세로방향으로돌려놓고 ImageView 위에있는 TextView 를선택한다. 그리고왼쪽과오른쪽및위의제약핸들 ( 작은원 ) 을마우스로끌어서부모인 ConstraintLayout에각각연결한다 ( 그림 20-9). 그림 20-9 20.5 제약추가하기 215
같은요령으로 ImageView 를선택하고왼쪽과오른쪽의상대제약을부모레이아웃에연결한 다. 그리고위쪽은 TextView 의아래쪽으로, 아래쪽은중앙버튼의위쪽과연결한다. 그다음에 ImageView가선택된상태에서자주사용하는속성만나타나게한다 ( 만일모든속성이나타나있으면모든속성보기버튼 ( ) 을다시클릭.) 그리고속성창위에서위쪽마진을 24로, 아래쪽마진을 8로변경한다. 또한, 높이와너비크기를 0dp 또는 match_constraint 로변경한다 ( 그림 20-10). 이렇게설정하면화면크기에따라레이아웃이변경될때 ImageView의크기가자동으로조정된다. 그림 20-10 그림 20-11 은현재 ImageView 에추가된제약연결을보여준다. 그림 20-11 216 CHAPTER 20 ConstraintLayout 예제프로젝트
이제는세개의버튼위젯에제약을추가하는것만남았다. 여기서는세개의버튼을하나의체인 (chain) 으로연결한다. 우선, 그림 20-2 의 Autoconnect 버튼을클릭하여로바꾼다. 제약의자동연결을활성화시키기위함이다. 그다음에 Buy Now 버튼을클릭한후 Shift 키를누른채로나머지두버튼도클릭하여세버튼모두선택되도록한다. 그리고 Shift 키를떼고 Buy Now 버튼에서오른쪽마우스버튼을클릭하고메뉴의 Center Horizontally를선택한다. 앞장에서얘기했듯이, 이렇게하면선택된위젯들간의양방향제약을쉽게추가하여체인을구성할수있다. 이제는세버튼이체인으로구성되었다. 기본적으로체인스타일은 spread 스타일이된다. 여기서는이스타일이적합하다. 끝으로, Buy Now 버튼의아래쪽과레이아웃의아래쪽을제약으로연결한다. 또한, 나머지두버튼도같은방법으로레이아웃의아래쪽에연결한다. ( 각버튼을선택하고아래쪽연결점 ( 작은원 ) 을클릭한후연결선을끌어서레이아웃의아래쪽에가져가면연결점이초록색으로나타난다. 이때마우스버튼을놓으면자동으로제약이추가된다.) 이모든작업이끝나면그림 20-12 와같이세버튼의제약이연결된다. 그림 20-12 20.6 레이아웃테스트하기 모든제약연결이추가되었으므로레이아웃편집기툴바의화면방향전환버튼을다시클릭하여가로방향으로화면을회전시키자. 이제는변경된화면크기에맞추어레이아웃이제대로나타날것이다. 이로써디자인시점에서레이아웃편집기로확인한결과는이상없이잘된것이다. 다음은앱이실제실행될때도잘되는지확인해보자. 실제장치나에뮬레이터에서우리앱을실행한후가로방향으로장치를회전시켜보자. 예를들어, 그림 20-13에서는에뮬레이터에서화면방향을전환한결과를보여준다. 20.6 레이아웃테스트하기 217
그림 20-13 위그림을보면알수있듯이, 앱을실행할때도레이아웃이제대로나타나는것을알수있 다. 이보다더복잡한레이아웃을디자인할때도마찬가지방법으로하면된다. 즉, 팔레트로 부터위젯을끌어서레이아웃에놓은후속성을설정하고제약을추가하면된다. 20.7 레이아웃검사기사용하기 사용자인터페이스레이아웃을구성하는컴포넌트들의정보는레이아웃검사기 (Inspector) 를사용해서볼수있다. 단, 실제장치나에뮬레이터에서앱이실행중일때만가능하다. 앞의그림 20-13과같이가로방향으로앱의화면이나타난상태에서메인메뉴의 Tools Android Layout Inspector를선택한다. 그리고 Choose Process 대화상자에서현재실행중인애플리케이션프로세스인 com.ebookfrenzy.layoutsample을선택하고 OK 버튼을클릭한다. 그림 20-14 처럼세개의패널이나타난다 ( 여기서는프로젝트도구창을닫은상태다 ). 그림 20-14 218 CHAPTER 20 ConstraintLayout 예제프로젝트
왼쪽패널에서는사용자인터페이스레이아웃을구성하는컴포넌트들의계층구조를보여준다. 그리고중앙패널에서는장치화면에나타난레이아웃을보여준다. 여기서특정위젯을클릭하면그것과연관된컴포넌트를왼쪽패널의계층구조에서찾아서표시해준다. 또한오른쪽패널에서는현재선택된컴포넌트의모든속성과설정값을보여준다. 20.8 계층구조뷰어사용하기 액티비티의뷰계층구조를자세히살펴보는데유용한도구가계층구조뷰어 (Hierarchy Viewer) 다. 이도구의주목적은현재실행중인애플리케이션에있는액티비티의뷰트리전체를자세하게보여주는것이다. 더불어레이아웃을화면에그리는성능도살펴볼수있다. 계층구조뷰어는안드로이드에뮬레이터에서실행되거나또는안드로이드개발 (development) 버전을실행하는장치에서만사용될수있다. 그러면이번장에서생성된 LayoutSample 애플리케이션에대해계층구조뷰어를실행해보자. 우선, AVD 에뮬레이터에서 LayoutSample 애플리케이션을시작시킨다. 그리고에뮬레이터에서화면이보일때까지기다리자. 그다음에안드로이드스튜디오메인메뉴에서 Tools Android Android Device Monitor를선택한다 ( 혹시 Disable ADB Integration 대화상자가나타나면 OK 버튼을누른다 ). 잠시후안드로이드장치모니터 (DDMS) 창이별도로열릴것이다. 안드로이드장치모니터메인메뉴의 Window Open Perspective... 를선택한후그다음대화상자에서 Hierarchy View를선택하고 OK 버튼을누른다. 그러면장치모니터창에계층구조뷰어가나타난다. 계층구조뷰어는여러개의패널로구성된다. 그림 20-15처럼보이는왼쪽패널의왼쪽위에있는 Windows 탭을클릭하면장치나에뮬레이터 ( 여기서는 Nexus5X) 에서현재동작가능한모든창 (window) 을보여준다 ( 계층구조뷰어에서는액티비티나프로세스대신 창 이라는용어를사용한다 ). 굵은글씨로된창이현재포그라운드로동작중인창이며, 여기서는 LayoutSampleActivity다. 그림 20-15 20.8 계층구조뷰어사용하기 219
우리애플리케이션프로세스인 com.ebookfrenzy.layoutsample.layoutsampleactivity 가선택된 상태에서툴바의버튼 ( 20-16). ) 을클릭하면뷰의계층구조가트리뷰로로드되어나타난다 ( 그림 그림 20-16 트리뷰패널밑에있는스케일바 (% 로표시됨 ) 를사용하거나마우스휠을돌리면트리뷰를줌인 / 줌아웃할수있다. 그러나대부분의경우트리가너무커서전체를한번에보기는힘들것이다. 그러므로마우스를클릭한채로끌어서트리를이동하여보거나, 또는오른쪽위에있는트리오버뷰 (Tree Overview) 패널안에서렌즈를이동시켜보면된다 ( 그림 20-17). 그림 20-17 220 CHAPTER 20 ConstraintLayout 예제프로젝트
트리뷰에는액티비티레이아웃에포함된뷰와더불어다른뷰들이같이나타날수있다는것을염두에두자. 예를들어, 화면맨위에나타나는액션바 (action bar), 또는액티비티가나타나는영역을제공하는레이아웃뷰등이다. 트리뷰에서특정노드를선택하면그것과일치하는사용자인터페이스요소가레이아웃뷰 ( 오른쪽하단의패널에서 Layout View 탭을클릭 ) 에빨간색으로강조되어표시된다. 그림 20-18에서는 ConstraintLayout 뷰가선택된경우를보여준다. 그림 20-18 마찬가지로, 레이아웃뷰에서특정뷰를선택하면그것과일치하는트리뷰의노드로이동되어강조표시된다. 뷰의추가정보는트리뷰에서그것의노드를선택하여얻을수있다. 해당노드를더블클릭하면팝업대화상자에서추가정보를보여준다. 예를들어, 그림 20-19에서는 LayoutSample 애플리케이션의 DETAILS 버튼노드를더블클릭했을때나타난대화상자를보여준다. (AVD 에뮬레이터를생성했던시스템이미지가구버전일때는팝업대화상자가나타나지않을수있다. 이때는 AVD 에뮬레이터를삭제하고최신버전으로생성한후앱을실행한다. 또한, 안드로이드장치모니터도다시실행시킨다.) 그림 20-19 20.8 계층구조뷰어사용하기 221
트리뷰에서는선택된레이아웃뷰를다시그리는작업을수행하거나, 또는트리뷰를 PNG 이미지파일로저장하는툴바버튼도제공한다 ( 트리뷰창의오른쪽위에있는각툴바버튼에마우스커서를대보면해당버튼의기능을설명하는텍스트가나온다 ). 또한, 선택된노드의뷰가그려지는성능정보를보기위해계층구조뷰어를사용할수도있다. 이때는루트뷰 ( 여기서는 ConstraintLayout) 로동작하는노드를선택한후그림 20-20에화살표로표시된툴바버튼을클릭하면된다. 그림 20-20 그러면각유형별 ( 측정치, 레이아웃, 그리기 ) 성능을나타내는점들이해당노드에나타난다 ( 그림 20-21). 여기서빨간색점은액티비티의다른뷰에비해그뷰의성능이느리다는것을나타낸다. 많은수의자식뷰들을갖고있는컨테이너뷰의성능은빨간색점으로나타날수있다. 왜냐하면각자식뷰들이모두그려질때까지기다려야하기때문이다. 그렇다고해서그컨테이너뷰가성능상의문제가있음을나타내는것은아니다. 그림 20-21 222 CHAPTER 20 ConstraintLayout 예제프로젝트
20.9 요약 안드로이드스튜디오의레이아웃편집기는안드로이드 7( 누가 ) 에추가된 ConstraintLayout 클래스와밀접하게통합되어있다. 이번장에서는레이아웃편집기를사용해서 ConstraintLayout 기반의사용자인터페이스를생성하는방법을알아보았다. 이때가장중요한것이제약연결을생성하는것이다. 또한, 레이아웃검사기와안드로이드장치모니터의계층구조뷰어를사용하는방법도살펴보았다. 이런도구들은사용자인터페이스레이아웃을구성하는컴포넌트를분석하는데유용하게사용될수있다. 20.9 요약 223
C H A P T E R 56 다중창예제프로젝트 앞장에서설명한다중창지원개요에이어서이번장에서는다중창지원을구현하는안드 로이드앱을만들것이다. 이번장에서생성하는프로젝트에서는여러개의액티비티를분할 화면모드와자유형식모드로구성하고관리하는방법을보여준다. 56.1 다중창프로젝트생성하기 우선, 새프로젝트를생성하자. 안드로이드스튜디오메인메뉴의 File New New Project... 를선택하거나웰컴스크린에서 Start a new Android Studio project를선택한다. Application name 필드에 MultiWindow를입력하고, Company Domain 필드에는 ebookfrenzy. com을입력한다. 안드로이드장치선택화면에서는폰과태블릿 (Phone and Tablet) 만선택하고, 최소 SDK 버전은 API 24: Android 7.0 (Nougat) 으로선택한다. 액티비티선택화면에서는 Empty Activity 를선택한다. 그리고마지막대화상자에서 Activity Name에 FirstActivity 를입력하고자동으로설정된나머지필드값은그대로둔다. Finish 버튼을눌러프로젝트를생성한다. 56.2 FirstActivity 의사용자인터페이스디자인하기 여기서는사용자인터페이스를하나의 Button 과 TextView로구성한다. 레이아웃편집기에열려있는레이아웃파일인 activity_first.xml의탭을클릭하여선택한후디자인모드로변경한다. 그리고 Hello World! 를보여주는 TextView를삭제하자. 585
자동연결 (Autoconnect) 이활성화된상태에서 (18장참조 ) 팔레트의 Text 부류에있는 TextView를마우스로끌어서레이아웃의중앙에놓고 ID를 mytextview 로변경한다. 또한 Widgets 부류에있는 Button을끌어서 TextView 밑에놓자. 그리고레이아웃편집기의제약추론버튼 ( ) 을클릭한다 (18장참조 ). 이렇게하면 Button의제약연결이자동으로추가된다. Button이선택된상태에서속성창의 text 속성을 Launch 로변경하고이값을문자열리소스로추출한다. 또한, onclick 속성을찾아속성값으로 launchintent를입력한다. 이것은버튼을클릭했을때실행될메서드다. 완성된레이아웃은그림 56-1 과같다. 그림 56-1 56.3 두번째액티비티추가하기 두번째액티비티는사용자가첫번째액티비티의버튼을클릭 ( 터치 ) 하면시작되게할것이다. 프로젝트도구창의 app java 밑에있는 com.ebookfrenzy.multiwindow 패키지에서오른쪽마우스버튼을누른후 New Activity Empty Activity 를선택한다. 그리고액티비티구성대화상자에서 Activity Name을 SecondActivity로변경하고 Layout Name은 activity_second로변경한다. 이액티비티는애플리케이션이시작될때바로실행되는것이아니므로 Launcher Activity 를체크하지말아야한다. 나머지는기본값그대로두고 Finish 버튼을누른다. 586 CHAPTER 56 다중창예제프로젝트
레이아웃편집기에열려있는레이아웃파일인 activity_second.xml의탭을클릭하여선택한후디자인모드로변경한다. 그리고팔레트의 TextView를마우스로끌어서레이아웃의중앙에놓고속성창의 text 속성을 Second Activity 로변경하고 layout_width 속성을 wrap_ content로변경한다. 완성된레이아웃은그림 56-2 와같다. 그림 56-2 56.4 두번째액티비티시작시키기 그다음에는 FirstActivity 클래스에 launchintent( ) 메서드를구현하는코드를추가하자. 편집기 의 FirstActivity.java 를선택한후다음코드를추가한다. package com.ebookfrenzy.multiwindow; import android.content.intent; import android.support.v7.app.appcompatactivity; import android.os.bundle; import android.view.view; public class FirstActivity extends AppCompatActivity { @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_first); } 56.4 두번째액티비티시작시키기 587
} public void launchintent(view view) { Intent i = new Intent(this, SecondActivity.class); startactivity(i); } 안드로이드 7(Nougat) 이실행중인실제장치나에뮬레이터에서앱을실행한후 Launch 버튼 을클릭하여두번째액티비티가시작되는지확인해보자. 56.5 다중창모드활성화하기 또한, 앱의다중창지원을활성화하도록다음과같이 AndroidManifest.xml 파일을변경한다 ( 매니페스트파일은프로젝트도구창의 app manifests 밑에있다 ). <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.ebookfrenzy.multiwindow"> <application android:allowbackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundicon="@mipmap/ic_launcher_round" android:supportsrtl="true" android:theme="@style/apptheme"> <activity android:name=".firstactivity" android:resizeableactivity="true"> <intent-filter> <action android:name="android.intent.action.main" /> <category android:name="android.intent.category.launcher" /> </intent-filter> </activity> <activity android:name=".secondactivity"></activity> </application> </manifest> 이책을저술하는시점에는다중창지원이기본적으로활성화되어있다. 그러나향후에는기 본설정이변경될수있으므로위와같이매니페스트에다중창지원활성화를추가하는것이 좋다. 588 CHAPTER 56 다중창예제프로젝트
56.6 다중창지원테스트하기 우선, 안드로이드 7.0 이상버전이실행되는에뮬레이터를시작시키자 (5장참조 ). 여기서는 Nexus 5X 에뮬레이터를사용한다 (55장의 55.2 절에서설명한대로자유형식모드를활성화시켜야한다 ). 앱을다시실행시켜서전체화면모드로나타난상태에서오버뷰버튼을길게눌러분할화면모드로전환하면그림 56-3 과같이 MultiWindow 앱과오버뷰화면이서로다른창으로나타난다. Launch 버튼을클릭하면첫번째액티비티와같은창에두번째액티비티가나타난다. 그리고두개의직사각형이포개진모양의오버뷰버튼을다시길게누르면전체화면모드로전환된다. Back 버튼을눌러서다시첫번째액티비티가나타나게한다. 이번에는자유형식모드로 MultiWindow 앱을실행해보자. 단, 이때는자유형식모드를지원하는장치나에뮬레이터에서앱을실행해야한다. 우선, 전체화면모드에서오버뷰버튼을짧게눌러서오버뷰화면이나타나게한다. 그리고 MultiWindow 앱의제목에나타난자유형식모드버튼 ( 그림 56-4에원으로표시됨 ) 을클릭한다. 그림 56-3 그림 56-4 그러면 MultiWindow 앱이자유형식모드의창으로나타난다 ( 그림 56-5). 그다음에 Launch 버튼을클릭하면첫번째액티비티가두번째액티비티로교체되어같은창에나타난다. 따라서두번째액티비티를다른창에나타나게하려면그와관련된플래그를설정한인텐트로시작시켜야한다. 그림 56-5 56.6 다중창지원테스트하기 589
56.7 두번째액티비티를다른창에서시작시키기 첫번째액티비티가두번째액티비티로교체되지않고다른창으로나타나게하려면두번째액티비티를다른태스크스택에서시작시켜야한다. FirstActivity.java 의 launchintent( ) 메서드를다음과같이변경한다. public void launchintent(view view) { Intent i = new Intent(this, SecondActivity.class); i.addflags(intent.flag_activity_launch_adjacent Intent.FLAG_ACTIVITY_MULTIPLE_TASK Intent.FLAG_ACTIVITY_NEW_TASK); } startactivity(i); 변경이끝났으면앱을다시실행시키자. 그리고오버뷰버튼을길게눌러분할화면모드로전 환한후 Launch 버튼을눌러두번째액티비티를시작시킨다. 이제는두번째액티비티가첫 번째액티비티와인접한다른창에나타날것이다 ( 그림 56-6). 그림 56-6 590 CHAPTER 56 다중창예제프로젝트
그림 56-6의상태에서오버뷰버튼을길게누르면 MultiWindow 앱이전체화면모드로전환된다. 그리고오버뷰버튼을짧게누르면오버뷰화면이나타난다. 거기에서 MultiWindow 앱의두번째액티비티를닫은후첫번째액티비티의자유형식모드버튼 ( 그림 56-4) 을클릭하여자유형식모드로전환한다. 그다음에 Launch 버튼을클릭하여두번째액티비티를실행시키면첫번째액티비티와다른창에두번째액티비티가나타난다 ( 그림 56-7). 그림 56-7 56.8 자유형식창의위치와크기변경하기 두번째액티비티가자유형식모드의별개창으로시작될때는기본적으로화면중앙에나타난다. 그러나다음과같이하면창의위치와크기를변경할수있다. 여기서는화면의제일왼쪽위에창이나타나면서가로와세로가각각 100픽셀크기를갖도록지정한다. 다음과같이 lauchintent( ) 메서드를변경하자. package com.ebookfrenzy.multiwindow; import android.app.activityoptions; import android.content.intent; import android.graphics.rect; import android.support.v7.app.appcompatactivity; 56.8 자유형식창의위치와크기변경하기 591
import android.os.bundle; import android.view.view; import static com.ebookfrenzy.multiwindow.r.id.mytextview; public class FirstActivity extends AppCompatActivity { @Override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.activity_first); } public void launchintent(view view) { Intent i = new Intent(this, SecondActivity.class); i.addflags(intent.flag_activity_launch_adjacent Intent.FLAG_ACTIVITY_MULTIPLE_TASK Intent.FLAG_ACTIVITY_NEW_TASK); Rect rect = new Rect(0, 0, 100, 100); ActivityOptions options = ActivityOptions.makeBasic(); ActivityOptions bounds = options.setlaunchbounds(rect); startactivity(i, bounds.tobundle()); } 마지막으로, 앱을다시실행하고자유형식모드로전환한후두번째액티비티를시작시키자. 그 리고두번째액티비티창이앞에서지정한위치및크기로나타나는지확인해보자. 56.9 요약 이번장에서는예제프로젝트를생성하여안드로이드앱의다중창지원을사용하는방법을알아보았다. 구체적으로는다중창지원의활성화, 새로운태스크스택으로액티비티시작시키기, 자유형식모드에서창의크기와위치를구성하기등이다. 592 CHAPTER 56 다중창예제프로젝트