2010년 9월 26일 일요일

Android Application Launch

이 글은 아래의 블로그를 번역 및 정리한 내용입니다.
http://multi-core-dump.blogspot.com/2010/04/android-application-launch.html
http://multi-core-dump.blogspot.com/2010/04/android-application-launch-part-2.html


첫번째 step은 app launch process를 자세히 이해하는 것이었다.

 안드로이드 어플리케이션들은 2가지 주된 이유로 기본적인 모바일 어플리케이션들과 다르다.

  1. 모든 안드로이드 어플리케이션은 Dalvik VM 인스턴스와 유일한 user ID가 할당된 자신의 세계에서 살고있다. 이 말은 분리된 프로세스에서 실행되는 것이다. 
  2. 안드로이드 어플리케이션은 다른 컴포넌트들로 구성되어 있고, 다른 어플리케이션 소유유의 컴포넌트들을 실행할 수 있다. 일반적으로 main 함수와 같은 single entry pointer를 가지지 않는다.
 어플리케이션 컴포넌들은

  • Activities : 특정 동작의 캡슐화, 추가적으로 GUI와 함께 조합되어지고, execution context를 제공한다.
  • Services : 어플리케이션 프로세스의 컨텍스트에서 실행되는 백그라운드 tasks들
  • Broadcast Receivers : Broadcast Intent listener
  • Content providers : Data storage and sharing interface of an app.
 안드로이드 프로세스는 리눅스 프로세이다. 기본적으로 인스톨된 모든 apk는 자신의 리눅스 프로세스에서 동작한다. 또한, 프로세스당 하나의 쓰레드가 존재한다. 메인 쓰레드는 메세지 큐로부터 메세지를 처리하기 위한 하나의 Loop 인스턴스를 가지고 있고, run함수의 모든 iteration에서 Looper.loop()를 호출한다(??).  메세지 큐에서 메세지를 꺼내오고, 처리하기 위한 적합한 함수를 호출하는 것이 looper의 일이다.

  언제 프로세스가 시작되는가? 프로세스는 요구되어질 때마다 시작된다. 사용자나 어떤 다른 시스템 컴포넌트가 당신의 apk에 속해 있는 컴포넌트(서비스, Activity, intent receiver)를 요청할 때 실행되어 진다. 시스템은 당신의 apk가 이미 실행되고 있지 않다면, 당신의 apk를 위해서 새로운 프로세스를 생산한다. 일반적인 프로세스들은 시스템에 의해서 종료될때까지 실행상태로 남아있다. 요점은 프로세스는 요구될 때 즉시 실행된다.
 예를 들어, 당신이 당신의 이메일에서 하이퍼링크(바로가기)를 클릭했다면, 웹페이지가 브라우저 윈도우상에서 오픈된다. 당신의 이메일 클라이언트와 브라우저는 두개의 독립된 어플리케이션들이고, 그것들은 두개의 독립된 그들의 프로세스에서 실행된다.

  init 프로세스는 Zygote를 시작시키고, Zygote는 System server를 시작시킨다. System server는 core platform services(Activity Manager services와 같은)들을 시작시킨다. 이 시점에서 첫번째 어플리케이션인 Home 어플리케이션을 시작할 준비가 된다.

 아이콘을 사용자가 클릭을 했을 때 많은 일들이 뒤에서 일어난다. 아래 그림을 보라.


 클릭 이벤트는 Binder IPC를 통해 ActivityManagerService의 startActivity(intent)를 호출하게 될 startActivity(intent)를 호출한다.(의역)

  • 첫번 째 단계는 intent object의 target에 대한 정보를 모으는 것이다. 이것은 PackageManager Object의 resolveIntent 함수를 사용하여 끝낸다. Package.MATCH_DEFAULT_ONLY 와 PackageManager.GET_SHARED_LIBRARY_FILES 플래그들은 기본적으로 사용된다.
  • Target의 정보는 intent 오브젝트에 다시 저장된다.
  • 다음 중요한 단계는 사용자가 intent의 target component를 실행할 권리를 가지고 있는 지 검사하는 것이다. 이것은 grantUriPermissionLocked 함수를 호출해서 끝낸다.
  • 사용자가 충부한 권한을 가지고 있다면, ActivityManagerServices는 target activity가 새로운 task를 실행을 요구하는지 검사한다. Task 생성은 FLAG_ACTIVITY_NEW_TASK, FLAG_ACTIVITY_CLEAR_TOP와 같은  intent 플래그에 의해서 결정된다.
  • 자, 이제 Process를 위한 ProcessRecord가 이미 존재하는지 검사할 시간이다.

 ProcessRecord가 null이라면, ActivityManager는 target 컴포넌트를 인스턴스화하기 위해서 새로운 process를 생성해야 한다.

 Process 실행의 3개의 뚜렷한 단계들이 있다.

  1. Process 생성
  2. Binding Application
  3. Activity 실행 / Service 시작 / Intent receiver 호출


 Process 생성

 ActivityManagerService는 소켓 연결을 통해서 Zygote process로 argument들을 보내는 startProcessLocked 함수를 호출함으로써 새로운 process를 생성한다. Zygote는 자신을 fork하고 ActivityThread를 인스턴스화하는 ZygoteInit.main 함수를 호출하고, 최종적으로 새롭게 생성된 process의 pid를 반화한다.

 아래 그림은 자세한 순서이다.



 Application Binding

 다음 단계는 특정 application을 process에 연결하는 것이다. 이것은 thread object에서 bindApplication를 호출함으로써 끝낸다. bindApplication 함수는 BIND_APPLICATION 메세지를 메세지 큐에 보낸다. 이 메세지는 handleBindApplication함수를 호출하는 handlerMessage 함수를 호출하는 handler object에 의해서 처리되어진다.(retrieve를 처리하다로 해석함). 

 아래 그림은 자세한 순서이다.


 Activity Launch

 이전 단계 후, 시스템은 프로세스의 메모리에 로드되는 application class들을 가지는 application에 대한 의무가 있는 프로세스를 포함한다(??). Activity를 실행하기 위한 호출 순서는 새로운 process를 생성하는거나 process가 존재하는거나 동일하다. 실제적인 launching의 과정은 application thread 오브젝트에서 scheduleLaunchActivity 함수를 호출하는 realStartActivity 함수안에서 시작된다. 이 함수는 LAUNCH_ACTIVITY 메세지를 메세지 큐에 보낸다. 메세지는 handleLaunchActivity 함수에 의해서 처리된다. 
 사용자가 Video browser application을 클릭했다고 가정하자. 아래 그림은 activity가 실행되는 자세한 순서이다.

 Activity는 onCreate 함수호출과 함께 관리되는 생명주기를 시작한다. activity는 OnRestart 함수와 함께 포그라운드로 올라오고, onStart 함수와 함께 사용자와 상호작용을 시작한다.

댓글 없음:

댓글 쓰기