개요
iOS에서는 AppDelegate가 출발점이고, 앱 정보는 Info.plist에 적는다. Android와 웹에도 똑같은 항목이 있다.
생김새가 많이 달라서, 처음에는 어색하지만 알아보자.
안드로이드에는 main()이 없다.
iOS 앱의 시작점은 하나이다. main -> UIApplicationMain -> Appdelegate.
아이콘을 눌러도, 푸시를 눌러도, 딥링크로 들어와도 결국 AppDelegate, SceneDelegate의 델리게이트를 거친다. 문은 하나인것이다.
근데 안드로이드는 아니다. 앱은 하나의 덩어리가 아니라 모듈의 모음이다. 시스템은 앱 전체가 아니라 필요한 부품 하나를 가져와 쓴다.
그래서 문이 여러개이다. 예를들어 아이콘을 누르면 런처용으로 표시된 화면(Activity)가 바로 생성된다.
이 말에 대해 좀더 자세히 알아보자.
iOS에서는 let vc = DetailViewController()이런식으로 내 코드가 생성함. 근데 안드로이드는 startActivity(Intent(this, DetailActivity::class.java)) 이런식으로 시스템에 이거 띄워달라고 부탁한다. 내가 짜는 코드는 Intent(요청서)만 보내고 객체를 실제 new로 만드는 곳은 시스템인것.
이렇게 시스템이 직접 생성할 수 있는 클래스가 바로 부품. 종류는 네가지(화면Activity, 백그라운드Service, 시스템소식BroadcastReceiver, 데이터공유ContentProvider)이고 시스템이 그 클래스를 알수있게 manifest에 등록해둔다.
시스템이 클래스 이름을 알고 직접 만들수있다. iOS도 Share Extension은 이런식으로 구현되어있음. 공유시트에서 내 앱을 고르면 본 앱의 AppDelegate를 거치지 않고 시스템이 Extension의 클래스를 직접 띄운다. 안드로이드는 앱의 모든 화면이 이런식으로 열릴수있는 문이라고 보면됨.
실제로 이 방법은 복잡하고 꼬일수있는 방법이다. 이렇게 만든이유는 2008년의 상황에 있다.
안드로이드 초창기의 램은 192메가 였음. 그런데 안드로이드는 처음부터 여러앱을 오가며 쓰는 경험을 추구했음. iOS는 멀티태스킹을 허용안햇음. 나가면 그냥 종료였고 iOS 4가서야 suspend가 생겻음.
메모리가 부족한데 앱이 뒤에서 살아있는것처럼 보일려면 몰래 죽였다가 사용자가 돌아오면 그 자리를 똑같이 다시 만들어주면됨.
여기서 화면은 시스템이 만든다가 핵심이됨. 시스템이 화면 클래스를 알고 직접 만들 수 있으니 앱 코드의 도움 없이도 사용자가 보던 화면을 되살릴 수있음.
iOS처럼 화면을 앱 코드가 만드는 구조였다면 시스템은 어느 화면을 어떻게 다시 만들지 알수없다.
또 앱끼리 부품을 빌려 쓰기에도 좋다. 그리고 시스템이 중앙 집권적 영향력을 가지면서 더 엄격하게 검사할수있다.
그러니깐 너무 복잡하다. 초기화를 한곳에 몰아둘수도없고 런타임이 자꾸 죽었다 깨니깐 static같은것이나 사용자 데이터도 사라진다.
그래서 요즘은 Activity를 하나만 두고 그안의 화면 전환은 Compose와 Navigation으로 하게, iOS처럼 내코드가 직접 관리하도록 바뀌었다.
그래서 어떤 부품이 어떤 문인지는 AndroidManifest.xml에 적는다.
앱이 다시 실행될때는 시스템이 새 프로세스를 띄운다. Application.onCreate()가 불리고 이때 onCreate(savedInstanceState)의 인자가 null이 아님. 죽기전에 저장해둔 상태가 있다는 말임. 시스템이 기억하는건 어떤클래스였고 어떤 Intent엿고 죽기전에 저장해둔 상태만 있다.
웹의 시작점 : URL
웹에도 main()은 없다. 브라우저가 주소를 서버에 요청하면 HTML 문서가 오고 브라우저는 그걸 위에서 아래로 읽다가
Intent: 화면과 앱 사이클을 오가는 봉투
iOS에서는 다른 곳을 연다는 내앱의 다른화면이든 다른앱이든 공유같은 상황에서 도구가다름.
안드로이드는 셋 다 Intent라는 봉투 하나로 한다. 봉투에 무엇을 적느냐에 따라 두 종류로 나뉜다.
명시적 Intent: 받는 클래스를 정확히 적는 봉투, 내 앱 안에서 이동할때 사용
val intent = Intent(this, DetailaCtivity::class.java) intent.putExtra(“docID”, 42) startActivity(intent)
암시적 Intent: 받는 사람 없이 하고 싶은 일만 적는 봉투
val intent = Intent(Intent.ACTION_SEND) intent.type = “text/plain” intent.putExtra(Intent.EXTRA_TEXT, “안녕”) startActivity(intent)
받는 사람이 비어 있으니 시스템이 이 일을 할 수 잇는 앱들을 찾아줌. 공유 시트가 뜨고 사용자가 고른다.
startActivity는 받을 앱이 없으면 ActivityNotFoundException으로 앱이 죽는다. 따라서 try-catch로 감싸야한다.
intent-filter가 뭔데?
아까 시스템이 이거 할수있는사람 손들어~ 했을때 들수있게 하는 필터.
action : 하고 싶은 일 category 부가조건 data : 앱 스킴
Context: Android 코드 곳곳에 나오는 손잡이
iOS에서 앱 환경을 사용할땐 전역 싱글톤을 사용함. Filemanager, Bundle, UserDefault같은것.
그러나 안드로이드에는 그런게 없음. 같은일을 전부 Context라는 객체를 통해서 진행함.
context.getString(R.string.title)