'Android'에 해당되는 글 2건

  1. 2011.10.10 What is Android?
  2. 2011.10.07 Context on Android
Android2011. 10. 10. 17:45

안드로이드란 모바일 장치에 포함된 OS와 미들웨어 주요 어플리케이션들을 말한다.
안드로이드 SDK에는 안드로이드 플랫폼위에서 실행할 어플리케이션 개발에 필요한 툴과 API를 제공한다. 개발언어는 Java를 사용한다.

* 특징
컴퍼넌트의 재사용과 재배치를 지원한다.
달빅(Dalvik)가상 머신으로 모바일기기에 최적화를 지원한다.
오픈소스인
웹킷엔진을 기반으로한  통합브라우저를 사용한다.
2D그래픽라이브러리와 OpenGL ES 1.0 스펙의 3D(하드웨어 가속 포함)를 지원한 최적화된 그래픽을 지원한다.
Data구조로는 SQLite를 지원한다.
오디오,비디오,이미지(Mpeg, H.264, MP3, AAC, AMR, JPG, PNG, GIF)를 지원한다.
GSM통신법을 지원한다.(장치마다 다를 수 있다)
블루투스, EDGE, 3G와 Wifi를 지원한다.
카메라, GPS, 나침반, 가속도계를 지원한다.(장치마다 다르다)
풍부한 개발 환경을 지원한다.(에뮬레이터, 디버그툴, 메모리와 성능 프로파일러, 이클립스 플러그인)

* 안드로이드 구조
아래표는 안드로이드OS의 주요 컴퍼넌트를 보여주고있다. 각 섹션은 하단에 자세히 보여주고 있다.



* 어플리케이션
안드로이드는 배처럼 안에 이메일 클라이언트, SMS, 달력, 지도, 웹브라우저 등등을 만들어 올릴 수 있다. 이 모든 어플리케이션은 자바 프로그래밍을 통해 만든다.

* 어플리케이션 프레임워크
안드로이드는 개발자에게 매우 풍부하고 혁신적인 개발 플랫폼을 제공한다. 또한 지역정보(LBS), 백그라운드 서비스, 알람 설정, 상태바에 정보를 알리는 등등 그 이상의 기능 활용에 자유롭고 유리하다.

개발자는 프레임워크에서 제공하는 코어 어클리케이션의 API까지 모두 접근이 가능하다.
어플리케이션 구조는 간단하며 컴퍼넌트의 재사용이 가능하도록 설계되었다. 어떤 어플리케이션은 그 자체로 사용이 가능하고 어떤 컴퍼넌트는 구성요소로서 조합하여 기능을 발휘한다. 이같은 메카니즘은 유저가 override나 재구성할 수 있도록 허용하고 있다.

밑단의 모든 어플리케이션은 시스템과 기능을 설정할 수 있다.
- 제공하는 View들은 풍부한 확장이 가능하게 설정할 수 있고 어플리케이션을 빌드하는데 일반적으로 사용한다. 이들은 리스트와 그리드, 문자, 버튼, 웹브라우저등을 포함한다.
- Content Provider들을 통해 다른 어플리케이션간에 데이터 공유/교환이 가능하다.
- 리소스 매니저를 통해 문자와 그래픽, 레이아웃 파일등을 코드없이 접근이 가능하다.(리소스를 추가하면 자동으로 XML에 추가되어 사용하게 된다. 대부분 정해진 이름의 폴더를 만들어 사용하게된다.)
- 알림매니저를 통해 모든 어플리케이션의 상태바에서 노출이 가능하다.
- Activity 매니저를 통해 어플리케이션의 수명과 네비게이션을 관리한다.(실제 안드로이드는 Activity라는 View단위로 화면을 구성하게 되며 일반적으론 Intent라는 클래스를 새로운뷰를 호출하고 관리한다.)

* 라이브러리
안드로이드시스템은 실제로 C/C++라이브러리들을 포함하고있다. 이러한 것들은 안드로이드 프레임워크를 통해 개발자에게 노출된다.
- 시스템  C 라이브러리 : 임베디드 리눅스 기반에 대한 표준 C 시스템 라이브러리 (libc)의 BSD 구현.
- 미디어 라이브러리 : PacketVideo의 OpenCORE를 기반으로 한다. OpenCORE는 MPEG4, H.264, MP3, AAC, AMR, JPG, PNG를 포함한 대부분의 오디오와 비디오 포맷과 정적 이미지 파일에 대하여 재생과 레코딩을 제공한다.
- Surface 매니저 : 2D와 3D의 복합적인 어플리케이션의 디스플레이 하부 시스템으로 접근 관리한다.
- LibWebCore :  안드로이드 웹브라우저와 웹뷰를 제공하는 웹브라우저 엔진이다.
- SGL : 2D의 하부 그래픽 엔진이다.
- 3D 라이브러리 : OpenGL ES 1.0을 구현한다. OpenGL ES 1.0는 하드웨어(그래픽카드)의 3D 가속을 사용할 수 있게 하며 높은 퍼포먼스를 자랑한다.
- FreeType : 비트맵과 벡터 폰트를 렌더링한다.
- SQLite : 관계형 데이터베이스 엔진으로 가장 가볍고 강력하다. 모든 어플리케이션이 이용할 수 있다.


* 안드로이드 런타임
안드로이드의 코어 라이브러리는 모두 자바의 코어라이브러리의 기능을 제공한다. 모든 안드로이드 어플리케이션은 달빅가상머신(Dalvik virtual machine)의 인스턴스로 해당 인스턴스 프로세스 위에서 실행된다. 달빅은 한개의 장치에서 여러개의 프로세스가 실행시에 매우 효율적이다. 달빅은 Dalvik virtual machine(.dex)라는 파일을 사용하여 메모리 사용과 사용된 흔적을 최소한으로 최적화 할 수 있다. (VM은 자바언어로 컴파일된 클래스들을 .dex 포맷으로 변환하여 실행한다)
달빅은 리눅스 커널을 기반으로 low-level 메모리 관리와 쓰레드의 하위 기능을 관리한다.

* 리눅스 커널
안드로이드는 리눅스 버전 2.6에서 제공하는 서비스와 보안, 메모리 관리, 프로세스관리, 네트워크 스택, 드라이버 모델 등을 사용/준수한다.

Posted by 버터백통
Android2011. 10. 7. 11:17

모든 개발언어에는 Context라는게 있다. 개념상으로도 쓰이고 실제적인 클래스로도 구현되어있다.
안드로이드의 Context를 조사하던 중 좋은 글을 펌한다;;;;

요즘 요령만 늘어...그냥 펌질만 해대고 있다~ㅋㅋㅋ
머 나만 빨리 찾아보면 되지~ㅋㅋㅋ


자료는 http://www.androidside.com/에서 퍼옴
자료 정리하신 huewu님 잘 보겠습니다~
머 이미 많은 분들이 퍼가셨네요~

<안드로이드 Context 는 수수께기가 많은 클래스입니다>


 Android Context Story

 저에게 안드로이드 Context 는 참 어려운 녀석입니다. 안드로이드 어플리케이션을 개발하며서 가장 빈번하게 사용되는 클래스 중 하나인건 분명한데, 지나가는 사람이 Context 가 뭔가요? 라고 물어 본다면, 스스로가 만족할 만큼 속 시원하게 대답할 수 있는 부분이 없습니다.

 관련해서 이런 저런 자료를 뒤져보고, 잘 읽히지도 않는 안드로이드 소스도 살펴보곤 했습니디만, 이거다... 라고 확실하게 짚고 넘어갈 건데기를 건져내지는 못했습니다. 그저 스스로에게 던진 질문 (안드로이드 Context 는 뭐지?)에 대한 나름의 대답이라는 의미로, 아는 한도내에서 Context 의 기능, Context 가 필요한 이유 그리고 Context 는 어떻게 태어나서 어떻게 사라지는지 정리해봅니다. 

Context 가 뭐지?

 우선은 정석대로. 안드로이드 개발자 사이트의 Context 클래스 오버뷰 내용을 살펴 봅니다.

Class Overview
Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching activities, broadcasting and receiving intents, etc.

어플리케이션 환경에 관한 글로벌 정보를 접근하기 위한 인터페이스. Abstract 클래스이며 실재 구현은 안드로이드 시스템에 의해 제공된다. Context 를 통해, 어플리케이션에 특화된 리소스나 클래스에 접근할 수 있을 뿐만 아니라, 추가적으로, 어플리케이션 레벨의 작업 - Activity 실행, Intent 브로드캐스팅, Intent 수신 등, 을 수행하기 위한 API 를 호출 할 수도 있다.
즉, Context  는 크게 두 가지 역할을 수행하는 Abstract 클래스 입니다.
  • 어 플리케이션에 관하여 시스템이 관리하고 있는 정보에 접근하기 

  • 안드로이드 시스템 서비스에서 제공하는 API 를 호출 할 수 있는 기능

 Context 인터페이스가 제공하는 API 중, getPackageName(), getResource() 등의 메서드들이 첫 번째 역할을 수행하는 대표적인 메서드입니다. 보통 get 이라는 접두어로 시작하는 메서드들이지요. 그 외에, startActivity() 나 bindService() 와 같은 메서드들이 두 번째 역할을 수행하기 위한 메서드라고 할 수 있습니다. 

왜 Context 가 필요할까?
  음... Context 의 기능은 대충 알만합니다. Context 와 관련되서 보다 곤란한 질문은 'Context 가 왜 필요하지?' 라고 생각합니다. 전역적인 어플리케이션 정보에 접근하거나 어플리케이션 연관된 시스템 기능을 수행하기 위해, 시스템 함수를 호출하는 일은 안드로이드가 아닌 다른 플랫폼에서도 늘상 일어나는 일입니다. 또, 그런 일들은 대게의 경우 (제가 아는한...) 어떠한 매개체를 거칠 필요없이, 직접적으로 시스템 API 호출하면 됩니다. 반면 안드로이드에서는 Context 라는 인스턴스화된 매개체를 통해야만 유사한 일들을 수행할 수 있습니다.

 예를 들어, C# 에서 어플리케이션 이름을 가져오고, 다른 어플리케이션을 실행시키는 코드는 아래와 같이 작성될 수 있습니다.
 //Get an Application Name.
 String applicationName = System.AppDomain.CurrentDomain.FriendlyName;

 //Start a new process(application)
 System.Diagnostics.Process.Start("test.exe");
 반면 에 안드로이드 Activity 에서는 아래와 같이 작성 해야 됩니다.
//Get an application name
String applicationName = this.getPackageName();

//Start a new activity(application)
this.startActivity(new Intent(this, Test.class));
 보시는 것 처럼, C# 의 경우 System 단에서 제공하는 정적 함수(static function)를 호출 함으로서 간단하게 할 수 있는 일들을 안드로이드에서는 Context 에 정의된 인스턴스 함수를 호출해야만 가능하게 되어있습니다. 즉, 위에서 처럼 반드시 인스턴스화된 Context 클래스(여기서는 this) 를 사용해야 되는 셈이지요. 

 왜 이런 차이가 생기게 된걸까요? 

 대답 하기 애매한 질문인 경우에, 질문을 거꾸로 뒤짚어 보면 서광이 비치는 경우가 있습니다. 안드로이드가 아닌 플랫폼에서는 어떻게 정적 함수 호출을 통해서 어플리케이션에 관한 정보를 가져오고, 시스템 함수를 호출 할 수 있는 걸까요? 

 제가 OS 에 관한 지식이 짧아, 꼭 찝어 이야기하기에는 어려움이 있지만... 일반적인 경우, 어플리케이션이 프로세스가 아주 긴밀하게 연결되어 있기 때문입니다. OS 커널의 가장 중요한 일 중 하나는 프로세스를 관리하는 것 입니다. (아마도..) 특정 프로세스가 특정 어플리케이션과 맵핑 된다면, 우리는 별다른 매개체 없이 시스템에 직접 프로세스의 정보에 관한 물어 볼 수 있고, 프로세스와 연관된 시스템 함수를 호출 할 수 있습니다. (이미 관리하고 있는 정보에 대해 묻고 있음으로)


 그런데 안드로이드에서 어플리케이션과 프로세스와의 관계는 조금 요상한 구석이 있습니다. 안드로이드에서 어플리케이션과 프로세스는 서로 독립적으로 존재입니다. 이와 관련된 구체적인 내용이나 이러한 구조를 갖는 원인에 대해서는 안드로이드 멀티태스킹에 관한 구글 개발자 블로그 포스트 에서 자세하게 다루어져 있습니다. (블로그에 번역해 두었으니 꼭 한번 읽어 보세요.)

 예를 들자면, 안드로이드 플랫폼에서는 프로세스가 없는 상황에도 어플리케이션은 살아있는 것처럼 사용자에게 표시되기도 하고, 메모리가 부족한 상황이 될 경우, 작동중이던 프로세스가 강제로 종료되고, 대시 해당 프로세스에서 작동중이던 어플리케이션에 관한 일부 정보만 별도로 관리하고, 이 후에 메모리 공간이 확보되면 저장되어있던 어플리케이션 정보를 바탕으로 새로운 프로세스를 시작하는등의 신기한 일이 벌어집니다.

 안드로이드에서도 프로세스는 당연히 OS 커널 (리눅스)에서 관리됩니다. 어플리케이션과 프로세스가 별도로 관리되고 있다면, 어플리케이션 정보는 어디에서 관리하고 있을까요? 안드로이드의 시스템 서비스 중 하나인 ActivityManagerService 에서 그 책임을 집니다. 그렇다면 ActivityManagerService 는 어떤식으로 어플리케이션을 관리하고 있을까요? 이외로 단순 합니다. 특정 토큰을 키값으로 'Key-Value' 쌍으로 이루어진 배열을 이용해 현재 작동중인 어플리케이션 정보를 관리합니다.

 거의 결론에 다다른거 같습니다. Context 는 어플리케이션과 관련된 정보에 접근하고자 하거나 어플리케이션과 연관된 시스템 레벨의 함수를 호출하고자 할 때 사용됩니다. 그런데 안드로이드 시스템에서 어플리케이션 정보를 관리하고 있는 것은 시스템이 아닌, ActivityManagerService 라는 일종의 또 다른 어플리케이션입니다. 따라서 다른 일반적은 플랫폼과는 달리, 안드로이드에서는 어플리케이션과 관련된 정보에 접근하고자 할때는 ActivityManagerService 를 통해야만 합니다. 당연히 정보를 얻고자 하는 어플리케이션이 어떤 어플리케이션인지에 관한 키 값도 필요해집니다.

 즉, 안드로이드 플랫폼상에서의 관점으로 살펴보면, Context 는 다음과 같은두 가지 역할을 수행하기 때문에 꼭 필요한 존재입니다.

  • 자신이 어떤 어플리케이션을 나타내고 있는지 알려주는 ID 역할 

  • ActivityManagerService 에 접근할 수 있도록 하는 통로 역할 

<나는 너가 누구인지 알고있다.>

 일반 OS 플랫폼에서 어플리케이션은 곧 Process 입니다. 특정 어플리케이션이 OS 에게 내가 어떤 Process 인지만 알려주면 어플리케이션 관련된 정보를 얼마든지 획득 할 수 있습니다. 이른바 자신의 존재 자체가 자신임을 증명해주는 '지문인식' 혹은 '홍채인식' 등의 '생체인식' 과 비슷한 개념이기 때문에 Context 와 같은 애매한 중간 매개체가 존재할 이유가 없습니다. 


< 내 Context 가 내가 누구인지 알고있다.>

 하지만 안드로이드 플랫폼은 조금 다릅니다. 비유하자면 '생체인식' 보다는 'ID카드' 를 통한 보안 시스템과 유사한 구조입니다. 특정 어플리케이션이 자신이 본인임을 확인 받을 수 있는 방법은 자신이 작동중인 Process 를 보여주는 것이 아니라, 자신이 건내받은 ID카드를 제시하는 것 입니다. 이 때 ID카드의 역할을 수행하는 것이 바로 Context 이고, 당연히 이 카드는 위변조가 가능하기때문에, 자신의 권한을 제삼의 어플리케이션에게 넘겨주는 PendingIntent 와 같은 기능도 가능해집니다.

 Context 는 언제 태어날까?

 Context 에 관한 마지막 질문은 약간의 부록과도 같습니다. Context 는 언제 태어날까요? 대답은 당연히 어플리케이션이 태어날 때입니다. 그렇다면 하나의 어플리케이션을 구성하는 각종 컴포넌트들 - Activity,Service,BroadcastReceiver 들은 모두 동일한 Context 를 공유해서 사용하고 있을까요? 저도 처음에는 그렇지 않을까 생각했었는데 알고보니 그렇지는 않더군요.

 Activity 와 Service 가 생성될 때 만들어지는 Context 와 BroadcastReceiver 가 호촐될 때( onReceive() ) 전해지는 Context 는 모두 서로다른 인스턴스입니다. 즉, Context 는 어플리케이션이 시작될 때는 물론이요, 어플리케이션 컴포넌트들이 생성될때마다 태어나는 셈입니다. 물론, 새롭게 생성되는 Context 들이 부모와 완전히 독립되어 있는 존재는 아니고 '거의' 비슷한 내용을 담고 있습니다.
 

< 파생된 Context 인스턴스들은 언제든지 부모 Context 에 접근할 수 있다.>

 어째 서 동일한 Context 인스턴스를 어플리케이션 컴포넌트들이 공유해서 사용하지 않고, 모두 서로 다른 (그러나 알고보면 알맹이는 거의 같은) 인스턴스를 만들어 사용하고 있을까요? 음... 어려운 문제입니다. 잘 모르겠네요. 일단 한 가지 분명한 원인이 있습니다.

 Context 의 기능 중, 시스템 API 를 호출하는 기능과 관련되어 한 가지 문제점이 있습니다. 어떤 어플리케이션 컴포넌트가 시스템 API를 호출하느냐에 따라서 서로 다른 결과가 나타나야 한다는 점입니다. 
예를들어, Service 에서 Activity 실행하기 포스트에서 언급한 것 처럼, 동일한 형태로 startActivity 메서드 호출하더라도, 일반적인 Activity 에서는 정상적으로 새로운 Activity 를 시작하게 되지만, Service 에서 호출할 경우에는 예외가 발생합니다. 만일 어플리케이션을 구성하는 Service 와 Activity 가 서로 동일한 Context 인스턴스를 공유하고 있다면 동일한 메서드 호출에 대하여 서로 다른 결과를 나타내도록 구현하지 못했을겁니다.

 따라 서, 현재 안드로이드 시스템은 어플리케이션 Context 를 기반으로 컴포넌트를 위한 Context 를 생성할 때 해당 Context 가 어떤 종류의 컴포넌트인지 알 수 있도록 약간의 표시를 해두곤 합니다. 

 또 한가지 안드로이드 개발팀의 코딩 스타일과 관련된 문제가 아닌가 하는 심증을 갖고 있습니다. 안드로이드 어플리케이션 컴포넌트들은 Context 를 포함하는 대신 상속받은 방식으로 구현되어 있습니다. Context 를 포함하는 방식이였다면 아마 작성해야할 코드량이 제법 늘어났을 것으로 짐작됩니다 (개별 컴포넌트 클래스마다 추상 API 들을 반복해서 구현해주어야 하니까...). 하지만 포함대신 상속받는 방식이 적용된만큼 당연하게 어플리케이션 Context 인스턴스를 어플리케이션을 구성하는 개별 컴포넌트들이 동일하게 사용하는 것은 어플리케이션 클래스 자체를 엄청나게 복잡하게 구현하지 않는 이상 불가능한 일이 되어 버렸습니다.

마무리

 결 론! 결국, 안드로이드 Context 는 여러가지 이유로 기존 플랫폼과는 다른 방식으로 어플리케이션을 관리하고 있고, 때문에 기존 플랫폼들에서는 단순하게 시스템 API 를 통해 할 수 있는 일들을, Context 인스턴스라는 조금은 귀찮지만 강력한 녀석을 통해 대행 처리하고 있다고 할 수 있겠습니다.


출처 : http://www.androidside.com/B46/11977
Posted by 버터백통