스마트웹앱콘텐츠전문가/안드로이드

[안드로이드]컴포넌트

9D4U 2018. 1. 31. 18:46
728x90
반응형

[안드로이드 컴포넌트] 안드로이드 앱을 구성하는 주요 컴포넌트에 대해 살펴보기

※안드로이드의 주요 컴포넌트 : 액티비티, 서비스, 브로드캐스트 리시버, 컨텐트 프로바이더

- 컴포넌트는 개발의 생산성을 높이고, 좋은 품질의 소프트웨어를 쉽고 빠르게 개발할 수 있도록 안드로이드 애플리케이션 프레임워크에서 제공해주는 것.

○ 컴포넌트 중, 가장 많이 사용되는 것으로는 액티비티, 서비스, 컨텐트 프로바이더, 브로드캐스트/리시버 가 있음.

- 액티비티('화면'을 제공) : 사용자와 앱 간의 인터페이스 역할을 담당. 

● 액티비티는 사용자가 보기에는 하나의 화면이지만, 내부적으로 볼 때는 뷰와 뷰 그릅으로 이루어져 있음.

● 기본적으로 안드로이드 개발 환경인 Android Studio에서 프로젝트를 생성하면 'app'이라는 Module내에 액티비티와 뷰, 뷰 그룹이 자동으로 생성됨.

● MainActivicy.java

onCreate() : 액티비티가 실행될 때 가장 먼저 호출되는 메서드. 좀 더 자세히 보면 setContentView('activity_main.xml 파일에 선언된 매개변수')라는 메서드가 호출되고 있는데,

     이 부분이 뷰와 뷰 그룹을 액티비티에서 보여주기 위해 사용됨.

액티비티를 앱 실행 시에 제대로 동작시키기 위해서는 AndroidManifest.xml 파일에 액티비티를 등록해주어야 함.

액티비티를 추가할 경우 AndroidManifest.xml에 추가되는 액티비티를 등록해주면 됨.

AndroidManifest.xml 파일에서 액티비티 추가는 <activity>에 등록하는데, 기본적으로 동작하기 위해서는 android:name은 반드시 추가해야 함.

android:name은 다음과 같ㅌ은 형식으로 등록함. [패키지명]+[액티비티 클래스명]

※추가로 생성한 액티비티를 실행시키기 위해서는 MainActivity 액티비티 클래스에서 실행 코드를 추가해 주어야 함.(액티비티 생명주기와 관련)

● 액티비티 생명주기 : 여러 개의 액티비티가 서로 호출하거나 호출됨에 따라 액티비티 전환이 일어나는데, 이 액티비티 전환을 화면 전환 으로 생각하면 이해하기 수월.

      이러한 화면 전환, 즉, 액티비티들의 상태가 변경되는 것을 '액티비티 생명주기'라고 함.

      ※액티비티 생명주기가 필요한 이유는 안드로이드는 pc와 달리 제한된 리소스를 가지고 있기 때문에, 한쪽으로 쏠리는 리소스 점유를 막기위하여

        액티비티 생명주기를 이용하여 액티비티 상태에 따라 우선순위를 정하고, 단말에 리소스가 부족할 경우 우선 순위에 따라 강제 종료하여 가용 리소스를 확보함.


액티비티 생성 : onCreate - onStart - onResume 액티비티 제거(뒤로가기) : onPause()-onStop()-onDestroy(), 탐색기 목록보기(백그라운드 상태): onPause()-onStop()

탐색기 목록에서 돌아오기(포그라운드 상태) : onRestart - onStart - onResume


● 액티비티 실행> Created: onCreate()

액티비티가 최초 생성 시에 호출되고, 초기화 설정 및 리소스에 해당하는 렐이아웃을 가져와 화면에 보여주기 위한 준비하는 단계.

= 기본적으로 각종 버트이나 리스트, 체크박스와 같은 뷰들이 배치되어 있는 레이아웃을 구성하고, 이러한 레이아웃의 뷰들로 상호작용을 할 수 있도록

  연결해주는 역할을 함.

Bundle타입의 파라미터가 존재하는데, 이것은 강제 종료 등의 상황이 발생했을 때 정보를 Bundle이라는 객체에 가지고 있다가 다시 실행될 때, onCreate()에서

기존 정보를 사용할 수 있도록 하기 위함.

● Created: onStart()

이 함수가 호출되는 경우는 onCreate()[액티비티가 실행될 때 호출], onRestart()[액티비티가 백그라운드에서 포그라운드 상태로 변경되는 시점에 호출] 함수 이후에 호출이 됨.

● Stopped > Started : onRestart()

액티비티가 백그라운드 상태(실행되어 있지만 보이지 않는 상태)에서 포그라운드 상태(실행되어 있고, 보이는 상태)로 변경될 떄 호출됨.

예) 홈버튼 사용시 후 다시 돌아올 떄, 다른 앱 실행 후 다시 돌아올 때.

● Started > Resumed : onResume(), Paused > Resumed : onResume()

액티비티가 화면에 표시되어 액티비티의 내용이나 버튼, 텍스트 입력등과 같은 일을 할 수 있음.

onStart()함수 이후에 호출됨.

이 함수는 빈번하게 호출될 수 있기 때문에 작업량이 많은 코드를 넣는 것은 권장하지 않음.

● Resumed > Paused: onPaused():

Resumed 상태에서 액티비티가 focus를 읽은 상태. = 사용자와 액티비티를 볼 수 있으나, 실제로 버트이나 텍스트 입력 등과 같은 작업을 할 수 없는 상태.

이 상태 이후부터는 언제든지 시스템으로부터 강제 종료 당할 수 있음.

onResume() 함수에서 했던 작업을 정리하는 일을 담당.

● Paused > Stopped : onStop()

Stopped 상태는 Paused 상태의 액티비티가 보이지 않응 상태를 의미.

액티비티가 포그라운드 상태에서 백그라운드 상태로 됨.

Stopped 상태가 될 때 onStop() 함수가 호출되며, 사용자가 백그라운드에서 필요한 작업을 추가하면 됨. 추가할 내용의 대부분이 onCreate()함수 또는

onStart() 함수에서 작업을 진행한 내용을 중지하거나 종료하는 내용이 들어감.


● Stopped > Destroyed : onDestroy()

Destroyed 상태는 액티비티가 백그라운드 상태에서 종료되거나 시스템에 의해 강제 종료 되면 Stopped상태에서 Destroyed 상태로 변경되는데,

이때 호출되는 함수가 onDestroy() 임.

액티비티가 종료될 때 할 수 있는 일들을 처리하는 함수.



- 서비스(백그라운드 기능을 지원) : 인터페이스 없이 백그라운드에서 데몬과 같이 동작하는 것. = 화면 없이 데몬 형태로 동작하는 것.

※ 액티비티(보이는, 화면이 존재하는) vs 서비스(보이지 않는, 화면이 존재하지 않는)

● 사용자 눈으로 볼 수 없는 작업을 주로 처리하는 데 사용되는 안드로이드 컴포넌트, 

안드로이드에서 액티비티가 종료되더라도 동작이 필요한 항목에 대해서는 지속적으로 작업을 하기 위해 만들어진 컴포넌트

예) 뮤직 플레이어 등


● 서비스를 호출하는 방식에 따라 두 가지 형태로 구분됨.

데몬 서비스(startService()):

Command를 전달 할 수는 있지만, 결과를 반환 받을 수 없음.

원격 서비스(bindService()):

연결이 완료되면, 원겨겨 서비스가 제공하는 함수를 호출하는 방식이기 때문에 반환되는 값을 받을 수 있음.

-> 이 두가지 서비스는 사용 형태가 조금 다르긴 하지만 둘 다 Service 클래스를 상속받아 작성

● 액티비티와 같이 생명주기가 존재함.

● 데몬 서비스

startService()로 호출되어 사용되는 서비스

사용용도 : '앱 잠금' 기능 등. = 모니터링

데몬 서비스에서 더 이상 할 일이 없는 경우 종료는 어떻게 하는가? 

- 외부에서 종료하는 경우 : 액티비티나 다른 서비스에서 인텐트 + stopService() 사용

- 데몬 서비스 자체에서 종료하는 경우 : 데몬 서비스 내에서 stopSelf() 실행

● 원격 서비스

프로세스 간의 통신(IPC)을 가능하게 하는 것으로, 클라이언트/서버 구조로 이해하면 쉬움.(안드로이드의 원격서비스는 RPC방법을 이용하여 프로세스 간 통신을 한다.)

cf)RPC(Remote Procedure Call): 하나의 프로세스에서 다른 프로세스의 API를 호출하는 방법으로 Stub을 이용.

   Stub : 클라리언트의 보조 객체에 해당하며, 원격지에 위치하고 있느느 프로그램을 대리하는 작은 루틴.

   Skeleton : Stub와 비슷한 역할로 서버의 보조 객체이고, 클라이언트의 Stub에서 데이터가 Marshaling되어 전송되면, Skeleton에서 Unmarsahling하여 원래의 형태로 복원함.

   AIDL(Android Interface Definition Loanguage) : 안드로이드에서 Marshaling하기 위해 정해진 형식이며, 이를 통해 프로세스 간 통신이 가능함.

● 원격 서비스 절차

(서버)1. [RemoteService] AIDL 파일을 생성

만약 .java 파일이 생성되지 않으면 build- make project를 선택하도록 함.

(서버)2. [RemoteService] 원격 서비스를 만듦

(서버)3. [RemoteService] AndroidManifest.xml 파일에 원격 서비스 등록

※주의할 점은 android:exported="true"이 부분을 반드시 추가해 주어야 함. 없으면 클라이언트에서 원격 서비스를 실행할 수 없음.

4. [Client] AIDL 파일을 생성

※사용할 원격 서비스와 동일한 패키지명을 사용

※ 사용할 원격 서비스와 동일한 클래스명 사용

-> 원격서비스의 aidl폴더를 복사하여 원격 서비스와 동일한 위치에 'Client'모듈에 복사

5. [Client] Stub 생성 여부 확인

스튜디오 보기 방식을 Project로 변경 후, build-generated-source-aid-debug에 .java파일을 확인

--- 원격 서비스 준비 완료. ---

6. [Client] 클라이언트에서 원격 서비스 연결

클라이언트에 필요한 부분 추가 : bindservice() 메서드를 이용하는 내용

cf) bindservice() : 안드로이드 바인더를 통해 원격 서비스에 접근이 가능하도록 제공. 즉, 서로 다른 프로세스인 클라이언트와 원격 서비스 간에 연결되어 메서드 호출이 가능

7. [Client] 클라이언트에서 원격 메서드 호출

클라이언트가 원격 서비스에 bindService()를 통해 정상적으로 연결 되면 원격 서비스에서 전달된 IBinder객체를 받음.

이 IBinder를 통해서 원격 서비스의 메서드를 호출가능.


8. [Client] 클라이언트에서 원격 서비스 연결 종료

●bindService() 함수의 이해

boolean bindService(Intent intetnt, ServiceConnection conn, int flags)

첫번째 파라미터로 intent 정보를 받음. intent 정보에는 접급하려는 원격 서비스 정보를 담음.

두번째 파라미터는 ServiceConnection 객체를 받음. 원격 서비스에 연결 결과를 ServiceConnection로 알려줌.

마지막 파라미터는 flags 값이 들어가는데, 여러 항목이 있음. 특별한 경우가 아니면 BIND_AUTO_CREATE를 사용.

※원격 서비스는 실제로 많이 사용되고 있기 때문에 반드시 이해하고 넘어가자!!!


● 안드로이드 인텐트와 인텐트 필터

액티비티와 서비스를 알아보는 과정에서 인텐트를 사용하였음.

인텐트는 컴포넌트 간에 필요한 데이터를 전달하고 컴포넌트를 실행하기 위해 사용됨. 

인텐트를 이용하면 액티비티 호출을 통해 액티비티 실행 뿐만 아니라 다양한 안드로이드 기능을 사용할 수 있음. 

예) 전화 걸기, 문자 보내기, 이메일 보내기, 웹 브라우저 실행하기 등

인텐트 사용방법에는 두 가지 방법이 있음.(명시적 인텐트, 암시적 인텐트)

cf) URI(Uniform Resource Identifier) : 안드로이드에서는 전화,이메일,문자,웹 브라우저를 실행할 때 사용됨.

  즉, 안드로이드에서 URI라는 것은 어떤 자원에 접근하기 위한 유일한 주소(전화 : tel, 문자: smsto, 이메일:mailto, 웹브라우저: http)


--> 인텐트는 안드로이드 컴포넌트 간에 데이터 전달 또는 컴포넌트 실행을 위해 사용됨.


- 브로드캐스트/리시버 : 배터리 정보, SMS 수신 정보 등을 브로드캐스트/리시버 컴포넌트를 이용하여 바로 알릴 수 있음.

브로드캐스느는 말 그대로 방송하는 것, 리시버는 방송하는 것을 수신하는 것.

● 안드로이드 브로드캐스트는 시스템에서 발생하는 경우와 써드파티 앱에서 발생하는 경우로 생각해볼수 있움

안드로이드 시스템에서 발생되는 브로드캐스트로는 배터리 정보, 스크린 ON/OFF, 부팅 완료, 앱 설치 완료 등. <- 이러한 브로드 캐스트 정보는 안드로이드 개발자 사이트에 명시되어 있음.

        써드파티 앱에서 발생시키는 브로드 캐스트 정보 같은 경우 앱 내에서 사용하거나 특정 앱과 약속하고 사용하는 경우 브로드캐스트 정보를 직접 선언하고 발생시킬 수 있음.                                                                                                                                                                                                                                                                   

● 안드로이드 리시버는 시스템에서 발생되는 브로드캐스트 정보와 써드파티에서 발생되는 브로드캐스트 정보를 수신할 수 있음.

● 브로드캐스트도 인텐트로 전달되고 이러한 인텐트는 등록된 인텐트 필터를 확인하여 해당 앱에서 리시버를 통해 수신함.

● 브로드캐스트 정보를 수신하기 위해 리시버를 AndroidManifest.xml 파일에 등록하는 것을 정적 등록이라고 함.

  동적 등록으로 정보 수신도 가능하지만...

  --> 브로드 캐스트 중에 모두 정적 등록(AndroidManifest.xml 파일에 등록)으로 사용할 수 없으며, 또한 모두 동적 등록(.java 만 사용)을 할 수 없음.

  예) 배터리 상태 정보와 스크린 On/Off 같은 경우 정적 등록으로는 브로드캐스트 정보를 수신할 수 없기 때문에 동적으로 등록한 경우에 한해서 브로드캐스트 수신 가능.


과제) 안드로이드 시스템에서 제공되는 여러 브로드캐스트를 예제 앱에 추가해 보기


- 컨텐트 프로바이더(데이터 공유) : '앱과 앱 사이의 데이터'를 주고 받을 수 있는 통로. = 앱 간에 데이터 '공유'를 위해 사용. 예) 전화 앱에서 제공하는 통화 기록.

일반적으로 컨텐트 프로바이더는 데이터베이스를 사용하는 대용량 데이터를 공유하기 위한 목적으로 만들어 졌지만, 꼭 데이터베이스가 아니더라도 컨텐트 프로바이더 사용법만 준수하면 공유가 가능.

※ 안드로이드에서는 앱과 앱간의 데이터 공유는 컨텐트 프로바이더 없이는 절대 공유 불가능.

● 컨텐트 프로바이더의 데이터 공유는 기본적으로 추가,삭제,업데이트 조회 등의 기능을 제공함.

데이터 추가,삭제,업데이트,조회 시에 구분하기 위해 URI를 사용함.

URI 예) Content://com.test.contentProvider(패키지명)/path/id

prifix |

......0Authority     |path |id

● 컨텐트 프로바이더와 '컨텐트 리졸버'

컨텐트 리졸버는 컨텐트 프로바이더에 URL을 이용하여 데이터를 요청함.

● 컨텐트 리졸버가 URI를 이용하여 컨텐트 프로바이더에 데이터를 요청하면 컨텐트 프로바이더는 URI를 확인하고 Local Database에서 데이터를 꺼내어 컨텐트 리졸버에게 전달한다는 것을 확인함.

● 컨텐트 프로바이더를 이용하여 다른 앱과 데이터를 공유할 수 있는 앱을 만들고, 컨텐트 리졸버를 이용하여 데이터를 가져올 수 있게 하기,ㅡ 0

● 컨텐트 프로바이더를 사용, 즉, 앱에서 데이터 공유위해서는 ContentProvider 클래스를 상속받는 클래스를 반드시 만들어야 함. -> ContentProver 클래스를 상속받으면 자동으로

  onCreate(), query(), insert(), delete(), update() 함수가 만들어짐.

  onCreate()함수에서는 데이터베이스 생성과 테이블을 DBHandler를 통해 만들어짐.

  만들어진 데이터베이스에서 insert()를 통해 (데이터)추가, query()를 통해 (데이터)조회, delete()를 통해 삭제, update()를 통해 갱신.

● AndroidManifest.xml 파일에 컨텐트 프로바이더 클래스를 등록하지 안흥면 접근이 되지 않음.

  또한, android:authorities와 android:exported="true"를 명시하지 않은 경우도 접근을 허용하지 않아 데이터를 제공하지 못함

※요약

안드로이드 주요 컴포넌트


1. 액티비티 : 안드로이드를 구성하는 가장 기본적이면서도 중요한 컴포넌트, 사용자와 앱간의 인터페이스 역할을 담당

2. 서비스 : 사용자를 방해하지 않고 백그라운드에서 작업을 처리하는 컴포넌트

3. 브로드캐스트 리시버 : 시스템에 발생하는 다양한 정보를 분별하여 수신하기 위해 사용.  

4. 컨텐트 프로바이더: 앱과 앱 사이에서 데이터를 주고 받을 때 사용.


728x90