시작하기
Hello World
- 기본 설정대로 프로젝트를 생성하면 아래의 4개 주요 파일을 볼 수 있다
- MainActivity.java
- activity_main.xml
- AndroidManifest.xml
- build.gradle
앱을 실행하면 이 클래스의 인스턴스가 실행되고 layout을 로드한다
액티비티의 UI를 정의한다
앱의 기본적인 특성을 기술하고, 각 컴포넌트를 정의한다
앱의 컴파일과 빌드에 관한 구성 설정
앱 컴포넌트
- Activity : UI가 있는 단일 화면. 액티비티는 한 번에 하나만 실행할 수 있다
- Service : 백그라운드에서 실행되는 요소
- ContentProvider : 외부로 공유하는 데이터 집합 관리
- BroadcastReceiver : 각 브로드캐스트는 Intent 객체로 전달된다
- Intent : 컴포넌트 간의 데이터 전달
- Activity, Service, BroadcastReceiver는 Intent로 활성화되고, ContentProvider는 ContentResolver의 요청으로 활성화된다
- public Intent(Context packageContext, Class cls)
- Intent putExtra(String name, ? value)
- 명시적 인텐트 : 수신 클래스 지정
- 암시적 인텐트 : 작업을 처리할 수 있는 컴포넌트로 안드로이드가 연결
- 브로드캐스트 인텐트 : 브로드캐스트 리시버로 등록된 모든 수신자에게 전송
- Fragment : Deprecated in API level 28
Project window » 우클릭 » New » Activity : 자동으로 매니페스트에도 추가된다
액티비티 시작 : startActivity() or startActivityForResult()
액티비티 생애주기 : onCreate(인스턴스 생성 시), onRestart(재시작), onStart(onCreate, onRestart 후), onResume(포그라운드), onPause(백그라운드), onStop(비가시영역 진입), onDestroy(소멸)
xml에서 saveEnabled 속성을 true로 하면 onSaveInstanceState, onRestoreInstanceState 메서드를 재정의하여 사용할 수 있다
서비스 시작 : startService() or bindService()
ContentProvider 이용 : ContentResolver.query()
브로드캐스트 송신 : sendBroadcast(), sendOrderedBroadcast(), sendStickyBroadcast()
매니페스트
- 구성 요소 선언, 요구 권한 식별, 최소 API 레벨 선언 등
- 다른 앱의 intent에 응답하기 위해 <intent-filter>요소를 해당 요소의 하위에 추가한다
- 요구사항 선언
- application 엘리먼트
- 컴포넌트 엘리먼트
- 인텐트 필터링 예
<activity>, <service>, <receiver>, <provider>
BroadcastReceiver는 registerReceiver()를 통해 동적으로 등록할 수 있다
↓ xml
많은 메모리를 필요로 하는 경우에만 android:largeHeap 속성 이용
설정이 완료되기 전까지 기능을 제한하려는 경우, android:enabled 속성을 이용해 Activity, Service, BroadcastReceiver의 동작을 막을 수 있다
↓ java
↓ xml
UI
- 안드로이드 UI는 layout(ViewGroup 객체)들과 widget(View 객체)들의 계층으로 이루어진다
- 길이 단위
- px : 픽셀. 장치마다 밀도가 달라 제각기로 표현된다
- dp : Density-independent pixels. 160dp는 밀도와 관계없이 1인치로 표시된다
- mm : 밀리미터
- in : 인치
- pt : 포인트 = 1/72 인치
- View
- 버튼, 텍스트 박스 등의 UI 요소
- id 속성 : @[+]id/ID
- layout_width, layout_height : 너비, 높이
- background : 배경. 지정하지 않으면 각 뷰의 기본값이 사용된다
- visibility : 가시성. visible | invisible | gone
- padding, layout_margin
- ViewGroup
- 자식 요소들을 어디에 위치시킬 지 조정한다
- ConstraintLayout
- LinearLayout
- GridLayout
- UI를 업데이트할 때엔 새 Runnable을 생성해 activity.runOnUiThread() 호출
- EventListener
- 테마 적용 예
- BottomNavigationView
TextView, EditText, Button, ImageView, Switch, ...
ID를 할당할 때는 +를 앞에 붙여 R 클래스의 상수로 등록되도록 한다
match_parent : 부모 요소의 크기만큼 할당, wrap_content : 내용물만큼 할당, 상수 지정 : 크기 고정
형제 요소들과 부모 레이아웃에 대한 거리를 통해 뷰를 조정한다
여러 요소들을 선택하여 우클릭한 뒤 chain으로 연결하면 한 번에 가로/세로로 배치할 수 있다
orientation 속성으로 horizontal | vertical 지정
gravity 속성으로 정렬 가능. center_horizontal(0x01), left(0x03), right(0x05), fill_horizontal(0x07), center_vertical(0x10), top(0x30), bottom(0x50), fill_vertical(0x70), center(0x11), fill(0x77)
baselineAligned 속성으로 요소들의 아래 줄을 일치시킬 지 여부를 지정할 수 있다
요소의 layout_weight 속성으로 너비/높이를 일정 비율씩 나눠가질 수 있다
화면의 가로/세로(columnCount/rowCount)를 잘라 만든 격자를 이용해 배치
com.google.android.material:material 포함
* Used icons made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY
SQLite
권한 요청
알림 보내기
매니페스트 설정 불필요
SensorManager
- https://developer.android.com/guide/topics/sensors/sensors_overview.html?hl=ko
- SensorManager, Sensor, SensorEvent, SensorEventListener
- 걸음 감지 예
↓ java
Location Manager
↓ xml
위치 소스 provider
- GPS : LocationManager.GPS_PROVIDER, 오차 ~수십 미터, 배터리 소모 많음, 긴 TTFF(Time To First Fix). ACCESS_FINE_LOCATION 권한 필요
- 기지국 : LocationManager.NETWORK_PROVIDER, 오차 ~수백 미터, 짧은 TTFF, 적은 배터리 소모. ACCESS_COARSE_LOCATION 권한 필요
- LocationManager.PASSIVE_PROVIDER : 다른 앱이 요청한 위치 정보를 사용, ACCESS_FINE_LOCATION 권한 필요
LocationManager
- List<String> getProviders (boolean enabledOnly)
- void requestLocationUpdates(String provider, long minTime, float minDistance, LocationListener listener) + removeUpdates
- void requestSingleUpdate (String provider, PendingIntent intent)
- void addProximityAlert (double latitude, double longitude, float radius, long expiration, PendingIntent intent) + removeProximityAlert
minTime : 업데이트 간 최소 시간(ms), minDistance : 업데이트 간 최소 거리(m)
근접 경보. 등록한 영역에 들어가거나 나갈 때 인텐트로 알림. ACCESS_FINE_LOCATION 권한 필요
expiration : 기한 내에 도착하지 못하면 알림 취소. -1이면 무기한
intent로 KEY_PROXIMITY_ENTERING이라는 boolean 값 전달. true면 들어가는 것, false면 나가는 것
LocationListener
- void onLocationChanged(Location location)
- void onProviderEnabled(String provider) + onProviderDisabled
- void onStatusChanged(String provider, int status, Bundle extras)
사용자가 위치 설정의 ON/OFF를 변경할 때
Deprecated Since 29 : 절대 호출되지 않는다
GPS를 이용하도록 설정했음에도 신호가 수신되지 않는 경우 등
status : LocationProvider.OUT_OF_SERVICE, LocationProvider.TEMPORARILY_UNAVAILABLE, LocationProvider.AVAILABLE
백그라운드, 절전 모드에서의 실행
- CPU 항상 켜기 필요 권한 : android.permission.WAKE_LOCK
- 화면 항상 켜기
- 주기적인 백그라운드 알람
- RTC : System#currentTimeMillis로 얻어지는 시각 기준
- ELAPSED_REALTIME : SystemClock#elapsedRealtime로 얻어지는, 부팅 후 경과 시간 기준
- RTC_WAKEUP, ELAPSED_REALTIME_WAKEUP : *_WAKEUP 타입은 기기가 자고 있으면 깨워서 실행시킨다
- Doze 모드
- AlarmManager#setAndAllowWhileIdle, setExactAndAllowWhileIdle를 사용해야 한다
- AlarmManager#setAlarmClock으로 설정된 경보는 정상적으로 실행되며, 실행 직전에 doze 모드가 종료된다
- AsyncTask
- Application 객체를 통한 공유
↓ java
xml : android:keepScreenOn="true" 또는
java : getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
↓ java
알람 type
네트워크 액세스 정지. WAKE_LOCK 무시. AlarmManager 경보 무시. Wi-Fi 검색 X, JobScheduler 실행 X, AbstractThreadedSyncAdapter 실행 X
onPreExecute(), onProgressUpdate, onPostExecute : 메인 스레드에서 실행된다
안드로이드 애플리케이션은 항상 Application 컴포넌트를 하나 갖고 있으며, Context#getApplication로 접근 가능하다
사용자 정의 Application을 사용하는 경우, 매니페스트의 name 속성을 변경해주고, getApplication() 결과를 캐스팅해야 한다
ProGuard
- 코드 최적화 및 난독화
- build.gradle의 안드로이드 영역에 아래를 추가
↓ gradle
최적화
performance몽키 테스트
- how-can-perform-monkey-testing-in-android-app
- CLI
- Android Studio
- File - Settings - Plugins > Install MonkeyMaster
- Run application
- Click 'Monkey' at the bottom bar > '+' button > Select device > OK
- Click 'Play' button > Fill popup > Run
↓ shell
- © Donggi Kim. MIT License
- w3css : No license
- highlight.js : BSD-3-Clause License
- MathJax : Apache License 2.0
- qrcodejs : MIT License