0. App fundamentals

본문은 안드로이드 DevGuide 번역, 정리한 것입니다


http://developer.android.com/guide/components/fundamentals.html


Application Fundamental



  

* Android Java 언어로 구현.

* appt_tool 묶여져서(bundled) android package 구성, 확장자 .apk 가진다

* 어플리케이션은 각자의 리눅스 프로세스를 가진다.

* 프로세스는 virtual machine 지닌다.

* 어플리케이션은 고유한 리눅스 user ID 할당받는다. 기본적으로 어플리케이션의 파일들은 자신만 볼수 있지만 이에 접근하는 다른 방법도 있다.


Application Components




 다른 어플리케이션의 일부를 활용할 있도록 하기 위해(다른 사람이 개발한 유용한 파트를 내가 개발할 필요가 없다) 안드로이드는 main 대신에 다른 entry 보유하고 있다. 이것이 바로 Component 이다

컴포넌트는 다음과 같다.


Activity


 가시적인 유저 인터페이스. 액티비티는 그려야할 기본 윈도우를 지니고 있으며 추가적인 윈도우(예를 들어 팝업 윈도우) 지닐 수도 있다.

Activity 클래스를 extends 해서 구현.


Service 


 백그라운드에서 돌아감. 음악을 플레이한다거나네트워크를 통해 데이터를 가져온다거나 – …  Service클래스를 extends 해서 구현,


실행중인 서비스에 접속하는 것이나 실행시키는 것도 가능하다. 연결된 동안 서비스가 제공하는 인터페이스를 통해 통신할 있다


다른 컴포넌트와 마찬가지로 서비스도 어플리케이션 프로세스의 메인 스레드에서 구동된다. 다른 컴포넌트나 인터페이스를 방해하지 않기 위해서 , 많은 시간을 요하는 작업은 스레드를 통해 구성하는 편이 좋다.


Broadcast Receiver


방송을 수신. 컴포넌트를 통해 그에 적절한 응답을 있다

BroadcastReceiver extends 해서 구현. 방송에 대한 반응으로 필요에 따라 NotificationManager 클래스-LED 밝힌다거나 단말기가 진동한다든가의 작업을 있는 클래스- 이용할 있다.


Content Providers


 다른 어플리케이션에서 활용가능한 어플리케이션 데이터 집합을 구성.

파일 시스템이나 데이터베이스 , 다른 여러 공간에 저장될 있다직접 호출되지 않고 Content Resolver 통한다. 이것이 프로바이더와 내부 통신을 가능하게 한다




특정 컴포넌트의 요청을 수행해야 할때마다 컴포넌트가 수행되고 있음을 확인하고, 필요하면 실행시킨다. 그리고 적절한 인스턴스가 필요하다면 만든다.


Activating Components : intents




Content Resolver 요청할때 Content provider들이 활성화 된다. 다른 컴포넌트들은 인텐트에 의해서 호출된다. 인텐트 객체는 메시지의 내용을 보유하고 있으며, Activity Service 위해 요청되는 액션과 데이터들의 특정 URI 이름을 붙인다


컴포넌트를 활성화 시키는 방법들 :


1 . startActivity() .

2 . startService() . onStart() 서비스에서 호출됨. 이때 서비스 호출부,서비스 사이에서 인텐트가 bindService() 통해 넘겨 있다.

3 . sendBroadcast(), sendOrderedBroadcast(),  sendStickeyBroadcast() 여기에 인텐트를 전달하여 방송을 초기화할 수있다. 이때에 방송을 수신하는 리시버들의 onReceiver() 호출된다.  


Shutting Down Components


특정 요구에만 활성화되는 Contentprovider BroadcastReceiver 과는 다르게 Activity Service 더이상 쓸모가 없을때 개발자가 명시적으로 종료시켜줄 필요가 있다. 이때 사용하는 메서드는


  • finish() , finishActivity() – 2번째 메서드는 startActivityforResult() 생성한 액티비티를 호출한 액티비티에서만 호출가능. –
  • stopSelf() , stopService()



메모리가 필요할때는 메서드가 호출되지 않아도 시스템이 강제 종료할 수도 있다.


The manifest file




 안드로이드가 어플리케이션 컴포넌트를 실행시키기 위해 존재하는 컴포넌트들에 대한 정의를 해주는 파일. 퍼미션등의 설정도 이곳에서 이뤄진다. (AndroidManifest.xml)


엘리먼트로는 <activity> , <service> , <receiver> , <provider> 등이 있을 있다. 이중에 리시버는 동적으로 코드에서 정의 수도있다.


Intent filters


인텐트 객체가 명시적으로 타겟 컴포넌트를 나타내고 있을 수도 있지만, 그렇지 않을때는 안드로이드가 1.(인텐트 오브젝트) 2.(타겟이 있는 컴포넌트의 인텐트 필터) 비교해서 타겟을 결정해야한다. 인텐트 필터는 어떤 컴포넌트가 어떤 종류의 인텐트를 다룰 있는지를 나타내는 것이다. 이것 역시 manifest 파일에 정의된다.


Activity and Tasks


어플리케이션에서 다른 어플리케이션의 컴포넌트를 실행시키는 경우가 있을 있다. 실제로 다른 어플리케이션이지만, 사용자에게 이것이 하나의 어플리케이션인듯 자연스럽게 이해시킬 필요가 있다. 이를 위해 이용하는 것이 Task이다. (일종의 스택)


Task에서의 액티비티의 동작은 액티비티를 실행시키는 인텐트 객체의 flags set <activity> 엘리먼트의 attributes set 상호작용으로 구체화 된다.


flags attributes set 다음과 같다.


FLAG_ACTIVITY_NEW_TASK  -----

FLAG_ACTIVITY_CLEAR_TOP -----

FLAG_ACTIVITY_RESET_TASK_IF_NEEDED -----

FLAG_ACTIVITY_SINGLE_TOP -----


taskAffinity -----

lanuchMode -----

allowTaskReparenting -----

clearTaskOnLaunch -----

alwaysRetainTaskState -----

finishOnTaskLaunch -----


: 액티비티는 액티비티를 호출한(startActivity) 액티비티와 같은 task 할당되는 것이 일반적인데 , startActivity 전달되는 인텐트가 플래그를 가지고 있다면 액티비티를 위해 새로운 task 찾는다. ( 완전 새로운 테스크를 할당하거나 액티비티와 어피니티() 같은 테스크에 할당하거나)


: 플래그를 가진 인텐트를 통해 액티비티가 새로 호출될때 이미 타겟 테스크에 인텐트를 다룰수있는 액티비티가 존재한다면 위에 있는 모든 액티비티를 버린다. 조합, 다른 테스크에 있는 존재하는 액티비티가 인텐트에 반응할 있도록 있다.


: <activity> 엘리먼트의 attribute. 가지 모드가 존재한다.

  • standard
  • singleTop
  • singleTask
  • singleInstance


  • 플래그가 없다면 모드일때 startActivity 인텐트의 테스크에 액티비티가 올라가게된다 모드의 액티비티는 여러 테스크에 소속될 수도 있고, 하나의 테스크가 액티비티의 인스턴스를 다수 가질 수도 있다. 여기까지는 2 같으며, 1 2 결정짓는 차이는 테스크의 탑에 이미 해당 인텐트를 처리할 있는 인스턴스가 있을때, 인스턴스를 재활용할지 혹은 새로운 인스턴스를 만들지이다.
  • 항상 테스크의 루트가 된다. 테스크에 오로지 하나의 인스턴스만이 존재할 있다. 모드에서는 어떤 인텐트의 요청이 있을때 이를 처리할 수있는 액티비티가 있으나 탑에 있지않을때에 그냥 인텐트를 버린다. (버리더라도 테스크가 포어그라운드로 오게 된다.)
  • 항상 테스크의 루트, 테스크에 하나의 인스턴스, 그러나 3과는 

다르게 테스크에 오로지 하나만 존재하게 된다. 항상 탑에 있기 때문에 인텐트의 요청에 반응한다.


: attribute true이면 , 그것이 시작한 테스크로부터 포어그라운드로 올라온 테스크에 어피니티가 있다면 테스크로 이동이 가능하다.


: 유저가 어떤 테스크를 멀리 떠나있다 돌아올때 , 어플리케이션의 초기상태로 돌아온다.


: 유저가 어떤 테스크를 떠나있다 돌아올때 , 아무일도 일어나지 않은 것처럼 테스크를 보존하고 있다.


: 일부만을 보존한다






Starting Tasks


Action “android.intent.action.MAIN” , category “android.intent.category.LAUNCHER” 설정하여 액티비티가 entry point 있도록 지정할 있다이러한 filter 액티비티 아이콘과 레이블이 어플리케이션 런쳐로 디스플레이 있도록 해줌와 동시에 task 실행할 있고 어느때건 실행된뒤에 되돌아 있는 방법을 제공한다.


두번째 기능은 중요하다 : 유저는 나중에라도 테스크를 떠나고 다시 되돌아 있다. 이러한 이유로, 테스크를 초기화 시키는  실행모드(launchmode)  - singleTask singleInstance – 반드시 해당 필터를 가지고 있을때만 사용 되어야 한다

필터들이 없을 때를 상상해보라! 하나의 인텐트가 singleTask 액티비티를 실행시키고, 새로운 Task 형성, 여기에서 사용자가 얼마간의 시간을 소모했다. 사용자가 홈키를 눌렀고, 사용자가 이용하던 테스크는 뒤로 밀려났다. 그리고 테스크는 런쳐가 아니기때문에 사용자가 다시 화면으로 돌아갈 방법이 없다


  • 유저가 되돌아왔을때 상태를 저장하기위해, singleTask singleInstance entry Activity 에서만 사용하라 !



launchMode 같이 새로운 테스크를 만드는 인텐트의 플래그 , FLAG_ACTIVITY_NEW_TASK 에도 비슷한 문제가 있다. 사용자가 되돌아 있도록 다른 방법을 강구해야된다. 어떤 엔티티는 (such as notification manager) 항상 외부 테스크로 액티비티를 실행킨다. 플래그가 항상 true 설정되어있다


사용자가 다시 되돌아가길 원하지 않는 케이스를 위해서는

finishOnTaskLaunch true 셋팅한다.




Processes and Threads 


어플리케이션에 처음으로 실행될때 안드로이드는 싱글스레드 리눅스 프로세스를 실행시킨다. 기본적으로 모든 컴포넌트들은 프로세스와 스레드에서 실행된다


하지만, 다른 프로세스에서 실행이 되도록 수정하는 것도 가능하며 아무프로세스에 추가적인 스레드를 구성하는 것도 가능하다.



Processes


Component 실행되는 프로세스는 메니페스트파일로 지정될 있다. 4 컴포넌트의 엘리멘트는 process 어트리뷰트를 가지고 있으며 이것으로 지정을 있다. 컴포넌트가 프로세스를 각각 가지고 있을지, 혹은 몇개만 공유하게 수도 , 심지어 다른 어플리케이션의 컴포넌트가 같은 프로세스에서 실행되는 것도 가능하다. – 같은 리눅스 유저아이디를 제공하고 같은 권한을 가지게 해서컴포넌트뿐만 아니라 <application>엘리먼트도 어플리케이션의 컴포넌트에 모두 적용되는 프로세스 속성을 가질수있다.