'Programming'에 해당되는 글 46건

  1. 2013.10.18 Singleton
  2. 2013.10.04 Content Providers
  3. 2013.10.04 Android Services
  4. 2013.10.01 Activities
  5. 2013.09.30 Android Activity State
  6. 2013.09.30 Stopping/Restarting Android Activity
  7. 2013.09.29 Pausing/Resuming Android Activity
  8. 2013.09.29 Creating/Destroying Android Activity
  9. 2013.09.29 Android Manifest File
  10. 2013.09.28 Android Application Components
Programming/Design Pattern2013. 10. 18. 12:37

싱글톤 패턴

1. public class Singleton { => 동기화 해야 하기 때문에 속도가 느림

  private static Singleton uniqueInstance;

  // 기타 인스턴스 변수

  private Singleton() {}

  public static synchronized Singleton getInstance() {

    if(uniqueInstance == null) {

    uniqueInstance = new Singleton();

    }

    return uniqueInstance;

  }

  // 기타 메소드

}


2. public class Singleton { => 처음부터 메모리를 소비하고 속도를 높일 수 있음

  private static Singleton uniqueInstance = new Singleton();

  // 기타 인스턴스 변수

  private Singleton() {}

  public static Singleton getInstance() {

  return uniqueInstance;

  }

  // 기타 메소드

}


3. public class Singleton { => 속도와 메모리 두 마리 토끼 잡기

  private volatile static Singleton uniqueInstance;

  // 기타 인스턴스 변수

  // volatile은 언제나 최신값을 가짐(두가지 특징)

  // 1. Thread에 변수가 공유되면 각자의 Caching 값을 같고 있다 업데이트 하지만 volatile 변수의 경우

  //     Caching 하지 않고 바로 메인모메로 영역의 변수로 접근한다.

  // 2. 동기화를 지원하여 동시에 여러게의 Thread가 접근할 수 없다.

  private Singleton() {}

  public static Singleton getInstance() {

  if(uniqueInstance == null) { <= 처음에만 동기화하고 다음에는 접근하지 않음

    synchronized (Singleton.class) {

       if(uniqueInstance == null) { <= Double-checking locking

  uniqueInstance = new Singleton();

    }

    }

  }

  return uniqueInstance;

  }

  // 기타 메소드

}

Posted by Brian B. Lee
Programming/Android2013. 10. 4. 02:17

Android Development - Content Providers 0/4

참조: http://developer.android.com/guide/topics/providers/content-providers.html


컨텐트 프로바이더는 정형화된 데이터의 셋의 접속을 관리한다. 보안을 위해 데이터를 캡슐화하여 제공한다. 콘텐트 프로바이더는 하나의 프로세스에서 동작하고 있는 다른 프로세스와 연결하는 표준 인터페이스이다.


컨텐트 프로바이더를 통해 데이터에 접속할 때, ContentResolver 객체를 이용하며 액의 Content 객체가 프로바이더의 클라이언트로써 포함된다. ContentResolver는 프로바이더 객체인 ContentProvider 추상클래스의 구현 객체와 통신한다. 프로바이더 객체는 데이터 요구를 클라이언트에게 받고 요구의 응답하고 결과를 리턴한다.


다른 앱들과 데이터를 공유할 필요가 없다면 자신의 프로바이더를 개발할 필요가 없다. 그러나 앱안에서 자신의 프로바이더가 앱 제안 검색을 제공할때 이것이 필요하고 복잡한 데이터나 파일의 복사 붙여넣기를 자신의 앱에서 다른 앱으로 전달할 때 필요로 한다.


안드로이드는 오디오, 비디오, 이미지 그리고 개인 연락처 등의 정보를 관리하는데 용도로도 컨텐트 프로바이더를 이용한다. 


좀더 정확하게 앞으로 4개의 파트로 나누어 설명하겠다.

1. Content Provider Basics

어떻게 테이블로 정의된 데이터에 컨텐트 프로바이더를 통해 접속할 것인가.

2, Creating a Content Provider

자신의 컴텐트 프로바이더를 어떻게 생성하는가.

3. Calendar Provider

안드로이드 플렛폼의 한 부분인 켈린더 프로바이더에 어떻게 접속하는가.

4. Contacts Provider

안드로이드 플렛폼의 한 부분인 컨텍트 프로바이더에 어떻게 접속하는가.

Posted by Brian B. Lee
Programming/Android2013. 10. 4. 01:44

서비스(Services)

참조: http://developer.android.com/guide/components/services.html


서비스는 백그라운드에서 롱런 작동을 하는 컴포넌트이며 사용자에게는 보이지 않는다. 다른 앱 컴포넌트에서 이를 실행시킬 수 있고 사용자가 앱을 스위치 시킨다하더라도 동작한다. 게다가 컴포넌트는 서비스와 묶일 수 있고 프로세스통신이 가능하다(IPC). 예를들어 서비스는 네트워크 트렌젝션, 음악 실행, 파일 I/O 동작이나 컴텐트 프로바이더와의 상호작용을 백그라운드에서 핸들링 할 수 있다.


서비스는 기본저긍로 두가지 폼을 가진다.

1. Started

앱 컴포넌트가 startService() 메소드 호출을 통해 서비스를 시작할 수 있는데 이를 "started"라 한다. 서비스가 한번 시작되면 이를 시작한 컴포넌트가 소멸되더라도 이 서비스는 독립적으로 백그라운드에서 실행되게 된다. 보통은 시작된 서비스는 하나의 동작을 하고 이에대한 결과를 호출자에게 리턴하지 않는다. 예를들어 네트워크를 통해 파일을 다운받거나 업로드하는 작업이다. 이런 작업이 끝난후 서비스는 자동 소멸된다.

2. Bound

앱 컴포넌트가 bindService() 메소드 호출을 통해 서비스를 시작할 수 있는데 이를 "bound"라 한다. 바운드 서비스는 클라이언트-서버 인터페이스를 제공한다. 이 인터페이스는 서비스와 상호작용하거나, 질의를 던지고, 결과를 받고, 심지어 프로세스통신(IPC)를 가로지를 절차를 수행할 수 있다. 바운드 서비스는 다른 앱 컴포넌트와 바인드 되어있을 때만 동작한다. 다수의 컴포넌트가 이 서비스를 한번에 바인드 시킬 수 있지만 모든 바인드가 풀렸을때, 이 서비스는 소멸된다.


이는 서비스를 독립적으로 시행시킬지 컴포넌트에 바인드 시킬지의 문제인데 이것은 쉽게 다음 두개의 콜백 메서드를 구현하는 것의 문제이다. onStartCommand() 메소드는 컴포넌트가 이 서비스를 시작하는 것을 허가하는 것이고 onBind()는 바인딩을 허락하는 것이다.


앱이 시작되었는지 바인딩되었는지 아니면 둘다 인지 상관없이 다른 앱 컨포넌트는 이 서비스를 사용할 수 있다. 이는 액티비티가 intent에 의해 다른 앱에서 실행될 수 있는 것과 마찬가지 인다. 하지만 메니페이스 파일에 명시함으로써 서비스 개인화가 가능하다. 이는 밑에 메니페스트에서의 서비스 명시(Declaring the service in the manifest)에서 다시 이야기하자.


주의. 서비스를 실행할 때 Application Not Responding 에러를 방지하기위해 새로운 스레드를 구성하여 서비스를 지원하자.


기초(The Basics)

서비스 구현을 위해서는 서비스 클래스의 서브클래스를 생성해야 한다. 몇몇의 콜백 메소드를 오버라이딩해야한다. 다음과 같은

onStartCommand(): startCommand()로 호출된다. 한번 실행되면 독립적으로 백그라운드에서 동작하고 자신이 stopSelf()하거나 다른 컨포넌트가 stopService() 메소드를 호출해 주어야 멈춘다.

onBind(): bindService()에 의해 실행되며 서버-클라이언트 인터페이스를 제공해야하며 IBinder 클래스로 리턴한다. 이 메소드는 꼭 구현되어야하고 바인딩을 원하지 않으면 null로 리턴한다.

onCreate(): 서비스가 실행될때 최초 한번 실행한다(onStartCommand()나 onBind()전에). 서비스가 이미 시작된 시점에서는 호출되지 않는다.

onDestroy(): 서비스가 더이상 상용되지 않을때 호출되며 이때 스레드나, 등록된 리스너, 리씨버 등의 리소스를 클린 업 해주어야 한다.


만약 컴포넌트가 startService()로 서비스를 콜하면 (onStartCommand() 콜백 메소드 실행) 자신이 stropSelf() 메소드를 호출하거나 다른 컴포넌트에서 stopService()메소드를 호출할때까지 동작한다. 


이번에는 컴포넌트가 bindService()로 서비스를 콜하면 (onStartCommand() 콜백 메소드 실행하지 않음) 이를 콜한 컴포넌트와 바인딩 되어있을 때까지 동작하고 모든 클라이언트로부터 바인딩이 풀리면 시스템이 이 서비스를 소멸한다.


메니페스트에서의 서비스 명시(Declaring the service in the manifest)

액티비티와 같이 모든 서비스는 메니페스트 파일에 명시되어야 한다. <application> 안에 <service> 태그 생성하고 꼭 생성해야하는 어트리뷰트는 android:name이고 액티비티와 같이 이 이름은 한번 생성되면 변경될 수 없다.

<service> 엘리먼트의 더 많은 정보는 다음을 참조: http://developer.android.com/guide/topics/manifest/service-element.html


액티비티와 마찬가지로 인텐트 필터로 암시적 인텐트를 통해 서비스를 실행시킬 수 있다. 그리고 인텐트 필터를 설정하지 않으면 다른 앱에서 암시적으로 접근할 수 없고 명시적 그러니까 클래스 명을 기입하여야만 이 서비스에 접근할 수 있다. 게다가 서비스를 개인화 하길 원한다면 android:exported 에트리뷰트 값을 false로 해주면 인텐트 필터가 있더라도 이에 접근할 수 없다.


스타티드 서비스의 생성(Creating a Started Service)

위에서 설명한 것을 다시 설명하지 않겠다. 그저 startService()메소가 호출되면 onStartCommand() 콜백 메소드가 실행되고 Intnet 객체를 받아 정보를 얻는다. 그리고 서비스 과부화로 사용자와 인터렉트하는 액티비티가 문제가 있을 수 있으니 서비스는 따로 스레드 돌려라.


전통적으로 스타티드 서비스를 생성하기 위해 두가지 클래스를 익스텐드 한다.


1. Servie

이것이 모든 서비스들의 기본 클래스이다. 기본적으로 메인 스레드를 이용하기 때문에 서비스 동작을 위해 새로운 스레드를 생성하라. 이는 어떠한 액티비티의 동작도 느리게 할 수 있기 때문이다.

2. IntentService

이는 Service 클래스의 서브 클래스이며 한번 하나씩 모든 요청들을 핸들링 하기위해 워크 스레드를 이용한다. 모든 요청을 한번에 동작시킬 필요가 없을 때 최고의 방안이다. 단지 onHandleIntent() 메소드를 구현하고 각각의 질의에따라 intent를 받고 이를 백그라운드에서 실행시킨다.


IntentService 클래스의 익스텐딩(Extending the IntentService Class)

대부분의 스타티드 서비스가 동시에 모든일을 수행하지 않기 때문에 IntentService 클래스가 최고의 선택이 될 수 있다.


intentService 크랠스는 다음의 동작을 한다.

- 액의 메인 스레드와 별개로 onStartCommand()에서 받은 인텐트들을 실행할 디폴트 워크 스레드를 생성한다.

- onHandleIntent() 구현 메소드가 한번에 한 인텐트씩 워크 큐를 사용하여 동작한다. 그래서 멀티 스레딩에 대한 염려를 할 필요가 없다.

- 모든 요청이 다루어지면 자동으로 서비스가 종료된다. 그래서 stopSelf()를 해 줄 필요가 없다.

- onBind()의 경우 자도응로 null을 리턴한다.

- onStartCommand()의 경우 Intent객체를 받아 워크 큐에 쌓아 놓았다 순서대로 onHandleIntent() 메소드를 사용한다.


IntentService를 익스텐드할 때 생성자에 super(String) 를 명시해야하고 인자값 String 생설될 스레드의 이름이 된다. 그리고 onCreate(), onStartCommand(), onDestroy() 메소드를 오버라이딩 할 수 있지만 첫줄에 super 클래스의 메소드를 호출하는 것을 잊지 말아라 이는 서비스의 스레드의 라이프를 핸들링 한다. 하지만 onBind()의 경우 예외이다 즉, super 크래스의 메소드 호출이 필요 없다.


다음으로 동시 질의 처리가 가능한 서비스 클래스의 익스텐드를 보겠다.


서비스 클래스의 익스텐딩(Extending the Service class)

만약 워크 큐를 통한 스타트 요구를 관리하느 데신 밀티스레딩을 이용한 서비스의 요구 처리가 필요하면 Service 클래스를 익스텐딩하여 구현할 수 있다.


구현은 스레드를 생성에 따라 달라질 수 있으며 onStartCommand() 메소드에서 어떤 int 값을 리턴하느냐에 따라 시스템이 이 서비스를 처우가 달라진다(소멸 여부). 다음은 리턴 벨류에 대한 설명이다.


START_NOT_STICKY

만약 시스템이 onStartCommand()를 리턴하고 서비스를 소멸시킨다면, 미결의 인텐트가 존재하지 않는한 서비스를 다시 생성하지 않는다. 이것은 필요하지 않을 때나 앱이 어떠한 완료되지 일을 쉽개 재시작할 수 있을 때 서비스를 돌아가는 것을 막는 가장 안전한 방법이다.

START_STICKY

만약 시스템이 onStartCommand()를 리턴하고 서비스를 소멸시킨다면, 서비스를 새로 생성하고 onStartCommand()를 호출하지만 마지막 인텐트는 전달하지는 않는다. 대신에 서비스를 시작시키기 위한 미결의 인텐트가 있는 것을 제외하고 시스템는 onStartCommand()를 null 인텐트를 인자로 호출한다. 이경우는 이 인텐트들은 전달된다. 이것은 명령을 실행하지않지만 독립적으로 실행되고 일을 기다리는 미디어 플레이어나 그와 관련된 서비스들에 적당하다.

START_REDELIVER_INTNET

만약 시스템이 onStartCommand()를 리턴하고 서비스를 소멸시킨다면, 서비스를 새로 생성하고 onStartCommand()를 호출하며 서비스에 전달된 마지막 인텐트는 전달한다. 모든 미결의 인텐드는 차례 차례 전달된다. 이것은 즉각적으로 재점유되는 파일 다운로드 같은 활동적으로 활동하는 일을 위한 서비스에 적합하다.


서비스의 시작(Starting a Service)

 인텐트를 인자로 startService() 메소드를 사용하여 서비스를 동작시킬수 있다. 그러면 onStartCommand() 콜백 메소드가 호출되고 만약 서비스가 처음 동작하는 것이라면 onCreate() 콜백 메소드가 먼저 실행되고 onStartComand() 메소드가 실행된다.


만약 서비스의 결과를 받아보고 싶다면, 서비스를 동작시킨 클라이언트가 브로드케스트를 위해 getBroadcast()로 PendingIntent를 만들어 Intent에 실어 서비스에 보낸다. 서비스는 이 브로드케스트를 이용하여 결과를 전달할 수 있다.


서비스 중지(Stopping a service)

 서비스는 각가의 라이프 사이클을 관리해야한다. 그렇지 않으면 시스템이 메모리를 회수하지 않는 한 서비스는 소멸되거나 멈추지 않고 onStartCommand()를 리턴한 후 계속 실행될 것이다. 그래서 stopSelf()나 stopService()메소드로 이를 정지시켜야 한다.


하지만 다수의 시작 요청에서 문제가 있을 수 있기 때문에 stopSelf(int)를 이요하여 시작요청에서 onStartCommand()의해 전달 받은 startId를 통해 각각의 서비스를 소멸시킬 수 있다.


바운드 서비스의 생성(Creating a Bound Service)

bindService() 메소드를 통해 서비스가 호출되며 서비스에는 onBind() 콜백 메소드가 구현되어 있어야하면 이는 IBinder 객체를 리턴한다. IBinder 객체는 서비스와 커뮤니키이션 하기위한 인터페이스를 가지고 있다. 이 서비스는 바인드된 앱들을 위해 존재하기 때문에 더이상 바인드된 앱이나 컴포넌트가 없다면 서비스는 소멸된다. (그래서 바운드 서비스를 정지 시킬 필요는 따로 없다.)


바운드 서비스를 생성하기 위해 클라이언트가 어떻게 서비스와 커뮤니테이션할지 인터페이스를 정의 해야한다. 서비스와 클라이언트간의 인터페이스는 IBinder 객체에 있어야하며 이는 onBind() 콜백 메서드의 리턴 값이다. 클라이언트가 IBinder 객체를 받으면 이것이 서비스와 인터페이스를 통해 통신하다.


다수의 클라이언트가 한번에 서비스와 바인드 될수 있다. 클라이언트가 서비스와의 통신이 끝나면 클라이언트는 unbindService() 메소드를 호출 할 수 있다. 그리고 모든 클라이언트가 바인드를 끝내면 서비스는 소멸 된다.


바이드 서비스의 구현은 다양한 방법이 있고 스타티드 서비스보다 더욱 복잡하다. 그래서 이 부분은 파트를 나누어 토의해 보자 참조:http://developer.android.com/guide/components/bound-services.html


사용자에게 공지 전달(Sending Notifications to the User)

서비스는 Toast Notifications나 Status Bar Notifications 를 통해 이벤트의 사용자에게 통지할 수 있다.

Toast Notification: http://developer.android.com/guide/topics/ui/notifiers/toasts.html

Status Bar Notifications: http://developer.android.com/guide/topics/ui/notifiers/notifications.html


Toast Notification은 잠시 화며에 메세지를 뛰웠다 사라지며 Status Bar Notifications의 경우 상태 바에 메시지가 노출되고 사용자가 이를 선택하여 액티베이트를 실행하는 등의 실행을 할 수 있다.


화면 전면에서 서비스 동작(Running a Service in the Foreground)

화면 전면의 서비스는 사용자가 이 서비스를 정확하게 인지하고 있다. 그래서 시스템이 메모리가 없을때 이 서비스를 죽일 수 없다. 전면의 서비스는 상태바에 이 서비스 상태를 공지해야 한다.


예를 들어 서비스로부터 음악을 실행시키는 음악 플레이어는 화면 전면에서 설정되어야한다 왜냐하면 사용자가  이 동작에 대해 정확하게 알고 있기 때문이다. 상태바는 현제 나오는 노래를 나태낼 수 있고 이를 통해 액티비티를 실행시키고 음악 플레이어와 상호작용할 수 있다.


이 서비스를 실행하기위해 startForeground() 메소드를 사용하며 이 메소드는 두가지 파라미터가 있다. 하나는 공지를 구분할수 있는 유일한 인티져 값과 Notification 객체이다. (요기서 인티져 값은 0 일수는 없다.)


이서비스는 stopForeground() 메소드로 삭제할 수 있으며 이는 boolean 값을 리턴한다. 이는 상태바 공지의 삭제위무를 같이 알려준다.


서비스의 라이프 사이클 관리(Managing the Lifecycle of a Service)

서비스의 라이프 사이클은 액티비티의 라이프 사이클보다 간단하지만 사용자가 인식하지 못하게 백그라운드에서 동작하기 때문에 서비스의 생사에 좀더 세심한 관심이 필요하다.


두가지 서비스 라이프 사이클이 있다.

- 스타티드 서비스(A started service)

startService()에 의해 실행된다. 독립적으로 동작하면 stopSelf() 메소드에 의해 멈춰진다. stopService()를 통해 다른 컴포넌트에서 정지시킬 수 있다. 서비스가 중지되면 시스템은 이를 소멸시킨다.

- 바운드 서비스(A bound service)

binService() 메소드가 다른 컨포넌트(클라이언트)에 의해 호출된다.클라이언트는 IBinder 객체를 통해 상호작용한다. 클라이언트느 unbindService() 메소드로 바인드를 풀수 있다. 다수의 클라이언트가 하나의 서비스에 바인드 될 수 있고 모든 클라이언트가 이 관계를 끊으면 시스템은 서비스를 소멸시킨다. (서비스가 자신을 정지시킬 필요가 없다.)


이 두가지 서비스 라이프 사이클리 완전히 분리되어있지는 않다. 예를들어 startService()로 시작된 음악 플레이어에 bindService() 메소드로 바인딩 시킬 수 있다. 이러한경우 stopService()나 stopSelf() 메소드는 서비스를 멈출 수 없으며 모든 클라이언트를 언바인딩 시킬때 서비스가 정지 된다.


라이프 사이클 콜백 구현(Implementing the lifecycle callbacks)

Service() 객체를 익스텐드한 클래스는 onCreate(), onStartCommand(Intent intent, int flags, int startId), onBind(Intent intent), onUnbind(Intent intent), onRebind(Intent intent), onDestroy() 메소드를 오바라이딩 함으로써 서비스 라이프 사이클을 관리 할 수 있다.



더 많은 Bound Services 의 정보는 다음 링크에서 참조: http://developer.android.com/guide/components/bound-services.html



Posted by Brian B. Lee
Programming/Android2013. 10. 1. 23:19

액티비티(Activities)

참조: http://developer.android.com/guide/components/activities.html


액티비티 명세(Declaring the activity in the manifest)

기본적으로 manifest파일에 <application> 태그 안에 <activity> 태그로 생성된다. attribute 로 android:name만 설정하면 되지만 한번 앱이 실행되면 이름을 바꿀수 없다.


인텐드 필터의 사용(Using intent filters)

<activity>는 <intent-filter> 태그를 사용하여 명시될 수 있다. 이는 다른 앱의 컴포넌트가 이 액티비티를 활성화할 수 있는 선언을 해 준다.


만약 다른 앱에서 이 액티비티를 실행시키기를 원하지 않으면 메인을 설정하는 <intent-filter>를 제외한 나머지 필터를 설정하지 않으면 된다.

- 인턴트 필터에 대한 더 많은 정보는 다음을 참조: http://developer.android.com/guide/components/intents-filters.html


액티비티의 시작(Starting an Activity)

다른 액티비티에서 startActivity() 와 Intent 객체를 인자로 원하는 액티비티를 실행시킬 수 있다. 그리고 인텐트는 정확하게 실행시키고싶은 액티비티를 설정할 수도있고 원하는 타입의 액티비티를 설정할 수도 있다(이때 시스템은 다른 액에서 적당한 액티비티를 선택한다). 그리고 인텐트는 적은양의 데이터도 옮길 수 있다.


그러니까 

명시적 인텐트가 있고(인텐트 객체 생성시 인자로 실행시킬 액티비티 클래스 설정)

암시적 인텐트가 있다(인텐트 객체 생성시 인자로 원하는 동작 타입과 그게 맞는 데이터만 넘김).

암시적 인텐트에 가치가 있는데 이는 다른 앱에서 원하는 액티비티를 불러낼 수 있고 만약 이런 앱이 많다면 사용자가 고를 수 있다. 예를 들어 이메일을 보내는 다른 앱의 액티비티를 불러내 보낼 당사자의 이메일 정보를 같이 이메일 앱으로 보낼 수 있다.


결과를 위한 액티비티의 시작(Starting an activity for a result)

startActivity()메소드 대신에 startActivityForResult()라는 메소드(인자: Intent intent, int requestCode)를 실행시킬 수 있다. 이 경우 다음 실행된 액티비티가 실행이 맞췄을 때 onActivityResult() 콜백 메소드로 인자 int requestCode, int resultCode, Intent data를 받을 수 있다. resultCode로 응답의 유무를 알 수 있고 requestCode로 startActivityForResult()메소드와 시퀀스를 맞추고 intent에서 데이터를 추출할 수있다.


액티비티 끄기(Shutting Down an Activity)

하나의 액티비티를 소멸하기 위해 finish() 메소드를 사용할 수 있고 finishActivity() 메소드를 사용하여 각각의 액티비티를 소멸할 수 있다. 하지만 굳이 액티비티를 액티비티 라이프싸이클에 의해 소멸시킬 필요가 없기 때문에 만약 필요하면 위의 메소드를 좀더 찾아 보길.


액티비티 라이프싸이클(Managing the Activity Lifecycle)

이전 포스팅에서 액티비티 라이프 싸이클에 대해 충분히 설명이 되었고 하나 추가하자면 onCreate(), on Start() … onDestroy()까지 모든 오버라이드하는 메소드는 super.onCreate() 같이 상위 클래스의 메소드를 첫줄에 추가해 줘야한다.



그리고 시스템이 스스로 액티비티를 죽일 수 있는 순간은 onPause(), onStop(), onDestroy() 가 호출 된 이후에만이다. 그래서 onPause()메소드가 실행되는 시점부터 자동으로 액티비티가 죽을 수 있으니 모든 중요 데이터는 onPause() 단계에서 중간 저장하고 가라 하지만 또 너무 많이 저장하면 매번 실행되기 때문에 시스템을 느리게 할 수 있는 요지가있기 때문에 선별하여 저장하는게 좋다.


액티비티 상태 저장(Saving activity state)

번들로 액티비티 상태를 저장하는 것은 이 부분역시 이전 포스팅에서 설명했다. 저장하는 onSaveInstanceState()와 복원하는 onRestoreInstanceState()는 클래스를 오버라이드한 후 바로 슈퍼클래스의 각각의 메소드를 호출해 주어야 한다. (만약 이런 상태 저장 자체를 원하지 않는다면 android:saveEnable 애트리뷰트에 false로 저장하거나 setSaveEnabled() 메소드를 호출하여 설정할 수 있다.) 그리고 간단하게 이걸 확인하는 방법은 기기를 로테이션 시켜서 가로모두로 바꾼하 돌아와보면 그 결과를 쉽게 알 수 있다.



컨피그레이션 변경 핸들링(Handling configuration changes)

스크린 로테이션, 키보드 보이기 나 언어 설정 등의 기기 컴피그레이션이 런타임동안 변할수 있다. 이러한 변경이 이루어질 때 시스템은 액티비티를 재생성한다(onDestory()->onCreate()). 그래서 가장 좋은 핸들링 방법은 위의 액티비티 상태를 저장하고 복귀하는 것이다. 


- 컴피그레이션 변경에 대한 더 많은 정보는 다음을 참조: http://developer.android.com/guide/topics/resources/runtime-changes.html


코디네이팅 액티비티(Coordinating activities)

액티비티A가 다른 액티비티B를 불러낼때 

1. 액티비티 A의 onPause() 메소드가 실행되고

2. 액티비티 B의 on Create(), onStart(), onResume()의 세게의 메소드가 순서대로 실행된다.

3. 그리고 마지막으로 액티비티 B가 화면에 보이면 액티비티 A의 onStop() 메소드 실행된다.


그러니까 액티비티 B가 실행되기 전 마지막 액티비티 A의 실행은 onPause() 때문에 액티비티 A에서 데이터 베이스 저장 후 액티비티 B에서 그 데이터를 쓰려면 액티비티 A의 onPause()에서 저장 시켜야 한다는 것이다 onStop() 에서가 아니라.

Posted by Brian B. Lee
Programming/Android2013. 9. 30. 22:04

Managing the Activity Lifecycle (4/4)


액티비티 다시 생성(Recreating an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/recreating.html


백버튼이 눌려지거나 finish() 메소드가 호출되는 액티비티가 소멸되는 몇몇 시나리오가 있다. 또 시스템에서 화면 전면의 액티비티가 많은 메모리를 필요로 하거나 하는 경우 액티비티를 소멸시킬 수 있다.


하지만 이렇게 시스템이 액티비티 객체를 소멸시켰을 때 사용자가 백버튼을 이용하여 다시 그 액티비티로 복기하려 할 때 소멸된 액티비티를 다시 불러올 수 있다. 이는 그 액티비티를 인스턴스화 하고 번들 객체에 key-value 짝으로 저장되어 있는 데이터를 가져온다. 이렇게 저장된 데이터를 인스턴스 상태(instance state)라고 한다.


기본적으로 시스템은 번들 인스턴스로 액티비티에 레이아웃에있는 View 객체 같은 것을 저장한다. 그래서 액티비티 인스턴스가 소멸되고 재생성될때도 그전의 상황을 재현할 수 있다. 하지만 이런 다시 재생성될때 같이 돌아오고 싶은 더 많은 정보들이 있다.(멤버 변수 같은)


액티비티 상태 저장(Save Your Activity State)

만약 더 많은 정보를 저장하려면 onSaveInstanceState() 콜백 메소드를 오버라이드 해야한다. 이때 Bundle 객체를 인자로 받고 이곳에 저장하고 싶은것을 Key-Value로 저장하면 된다. 이렇게 예상 밖에 액티비티가 소멸됐다가 나중에 다시 재생성될때 onRestoreInstanceState()와 onCreate() 두 메소드에 인자로 Bunde 객체를 보내 이곳에서 위에서 저장한 정보를 불러올 수 있다.

한마디로 무조건 일어버리면 안돼는 정보는 Bundle에 저장해라.(물론 View의 스크롤 포지션이나 에디트 텍스트의 문장 같은 자동으로 저장되는 것이 있다.)


액티비티 상태 다시 불러오기(Restore Your Activity State)

위에서 Bundle객체를 가지고 오는 법이 onCreate()와 onRestoreInstanceState() 두가지 방법이 있다고 했는데 onCreate() 의 경우 Bundle객체가 null일 수 있기 때문에 if 문으로 null 체크를 해주어야 하지만 onRestoreInstanceState()의 경우 번들 객체가 있을 때만 메소드를 콜백하기 때문에 null 체크를 해줄 필요가 없다.

Posted by Brian B. Lee
Programming/Android2013. 9. 30. 21:03

Managing the Activity Lifecycle (3/4)


액티비티의 멈춤과 재시작(Stopping and Restarting an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/stopping.html


- 사용자가 앱 사용중 화면 전면에서 사라진후 다시 홈 스크린에서 이 앱을 실행시키거나 대체된 앱에서 다시 본 앱으로 돌아왔을 때, 앱티비티가 다시 실행된다.

- 액티비티에서 다른 액티비티를 실행시켰을때 그 전 액티비티는 멈춰진다. 만약 사용자가 뒤로가기 버튼을 눌러도 첫번째 액티비티는 다시 시작된다.

- 앱을 사용할때 전화를 받았을 때도 액티비티는 멈춰진다.


액티비티는 멈춤과 재시작을 위해 onStop()과 onRestart() 메소드를 제공한다. 이는 Paused 상태와 다르게 화면에서 액티비티가 완전히 사라진다.


Note. 시스템이 스톱될때 시스템 메모리안에 액티비티 인스턴스를 저장하기 때문에 onStop(), onRestart() 심지어 onStart() 메소드를 구현할 필요가 없을 수 있다. 그래서 심플한 관계를 가지고 있는 액티비티간의 동작은 onPause() 메소드를 이용한 시스템 리소스를 컨트롤 하는 작업만이 필요할 수 도있다.


액티비티 정지(Stop Your Activity)

스톱이 되었을때 더이상 사용자에게 보이지 않기 때문에 대부분의 리소스를 릴리즈 해야한다. 만약 시스템 메모리 되찾기가 필요하면 시스템은 이 인스턴스를 재거되거나 심지어 필요에따라 아무 알람없이 onDestory() 콜백을 호출하여 종료시킬 수 있다. 그래서 메모리 누수를 막기위해 onStop() 메소드에서 리소스를 릴리즈 시켜줘야 한다.


액티비티가 스탑될 때, 액티비티 객체는 메모리에 상주 데이터로 남게 되고 액티비티 재개에서 리콜되어 진다. 그래서 거의 대부분의 경우 재초기화의 필요성이 없다.


액티비티의 시작과 재시작(Start/Restart Your Activity)

액티비티가 화면에 전면에 다시 나타날때 onRestrt()메소드가 실행된다. 그리고 바로 시스템은 onStart() 메소드를 호출하고 이 메소드는 액티비티가 화면에 보일때 마다 이루어진다. 하지만 onRestart() 메소드는 Stopped 상황에서 resume 될때만 호출된다.


보통 onRestart() 메소드는 사용되지 않고 특정 상황에서 리소스를 릴리즈 하기위해서만 사용된다. 그리고 보통은 onStart()와 onStop()를 한쌍으로 본다.


결국 정리하면 

onStart()는 

1. 처음 앱이 시작할 때 

2. 액티비티가 stopped 됐다 Resumed 로 돌아갈때

이렇게 두가지 경우에서 실행되고


onResume()는 

1. 처음 앱이 시작할 때 

2. Pused 됐다 돌아올 때 

3. stopped 됐다 돌아갈 때

와 같이 액티비티가 화면의 전면에 나타날때는 모두 실행된다.


onRestart()는 

1. Stopped에서 Resumed로 갈때 한번만 실행된다.


onPause()는

1. Pauee() 만 될때 (전화가 오거나 알람이 울어 포커스를 잃었을 때)

2. Stopped 상태가 되는 과정에 실행

3. Destroyed 상태가 될는 과정에 실행

그러니까 Resumed 상황에서 변경되면 모두 발생


onStop()는

1. Stopped 상태로 변할 때

2. Destroyed 상태로 변할 때


onDestroy()

1. Destroyed 상태로 변할 때 한번


상태가 변하면서 거쳐가는 과정이 있기 때문에 중간 중간 메모리 관리하면 된다. 그리고 결국 액티브 인스턴스가 Destroyed 상태로 변하기 전까지 메모리로 보관대기 때문에 크게 객체를 따로 보관할 필요는 없지만 객체에서 생성한 스레드 같은 것은 잘 관리 해주어야 그렇지 않으면 시스템에서 예고 없이 앱을 종료시킬 수 있다.


다음에는 Managing The Activity Lifecycle 의 마지막으로 위와 같이 잘 작동하다 시스템이 맘대로 지가 메모리가 모잘라 Stopeed 상태인 내 앱을 죽여버렸을 때 어떻게 데이터를 유지할 지 보겠다.

Posted by Brian B. Lee
Programming/Android2013. 9. 29. 22:08

Managing the Activity Lifecycle (2/4)


액티비티의 멈춤과 재개(Pausing and Resuming an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/pausing.html#Resume


앱이 실행되는 동안 다른 비주얼 컨포넌트로 가리워 질 수 있다 이때  Puse 동작이 이루어 진다. 이때 반투명 액티비티가 실행되거나 부분적으로 액티비티가 가리워 진다. 


하지만 모두 가려졌을 때 이것은 stoped 상태가 된다.


처음 액티비티가 Paused 상태가 되면 onPause() 메서드를 실행시킨다. 이때 모든 실행은 더이상 진행할 수 없게 되고 사용자 진행을 위해 어느 정보들은  저장된다. 그리고 다시 사용자가 이 액티비티로 돌아올 때 onResume() 메소드가 실행 된다.


액티비티 중지 (Pause Your Activity)

- 애니메이션을 중지하거나 CPU를 소모하는 동작들을 중지

- 오직 사용자가 변화를 저장되어지길 기대하는경우에만 저장되지 않은 변화를 관리한다. (이메일 드레프트 같은)

- 사용자가 필요로 하지 않은 브로드케스트 리씨버나 센서(GPS같은) 사용같은 베터리 라이프에 영향을 미치는 시스템 자원들을 릴리즈한다.


보통 onPause() 메소드를 사용하여 연구 보관 저장장치에 사용자 변화(개인 정보가 입력되었을 때)를 저장하지 않는다. 하지만 특정 정보(이메일 드레프트 같은)의 경우 사용자 기대에 의해 저장되어 질 수 있다. 물론 CPU에 부화를 주는 데이터베이스 쓰기 작업 같은 경우 다음 액티비티의 트렌젝션 화면이 느려질 수 있다 이런경우를 피해야겠다.


Note: 액티비티가 멈출때 액티비티 인스턴스의 메모리 정보는 지켜지면 재개될때 리콜된다.  그래서 다시 컨포넌트를 재초기화 할 필요는 없다.



액티비티 재개(Resume Your Activity)

액티비티가 Pause 되었다 다시 재개되면 onResume() 메소드를 호출 한다.


처음 액티비티가 생성될때를 포함해 액티비티가 전면에 실행 될때 마다 이 메소드는 호출 된다는 점을 인지해야한다. 그래서 onPause(), onResume() 메소드 호출 시 상황에 맞는 초기화를 잘 해주어야 한다. 


onResume()과 onPause() 메소드는 한 쌍이기 때문에 onPause()에서 camera.release() 되면 onResume()의 경우 initializeCamera()해주는 것과 같이 관리 되어야한다. 

Posted by Brian B. Lee
Programming/Android2013. 9. 29. 21:17

Managing the Activity Lifecycle (1/4)


액티비티의 시작(Starting an Activity)

참조: http://developer.android.com/training/basics/activity-lifecycle/starting.html


main() 메서드로 시작하는 다른 프로그램과 달리 안드로이드는 Activity의 인스턴스의 콜백으로 시스템이 시작한다. 

참고: 콜백? vs 호출?

콜백함수와 함수 호출의 차이는 제어권에 있다

호출자가 -> 피호출자 호출(일반적인 함수 흐름)

피호출자 -> 호출자 호출(콜백의 함수 흐름)

즉, 안드로이드에서 콜백함수를 실행시켜줘야 앱이 동작한다는 거다.


라이프사이클 콜백의 이해(Understand the Lifecycle Callbacks)



그림 1. Lifecycle Callback Status


액티비티의 복잡성에따라 모든 인스턴스를 라이프사이클을 정의해 줄 필요는 없지만 사용자의 기대치에는 부합해야한다. 라이프 사이클의 메서드를 정의함으로써 다음과 같은 올바른 행동을 정의할 수 있을것이다.

- 앱을 사용할 때 전화를 받거나 다른 앱으로 변경시 액의 문제를 방지할 수 있다.

- 사용자가 앱을 상요하지 않을 때, 시스템 자원을 소비를 피할 수 있다.

- 앱에서 빠져나가거나 앱의 마지막 상황으로 돌아갈 때, 사용자의 진행사항을 일지 않을 수 있다. 

- 화면의 변경에서 사용자의 진행사항이나 문제를 피할 수 있다.


그림 1.에서 다른 많은 상황들이 있지만 정적인 상황은 결국 세가지 밖에 없다.

1. 재점유된(Resumed): 액티비티가 화면 전경에 보이고 사용자가 사용할 수 있다. (running이라고도 한다)

2. 중지된(Paused): 액티비티가 다른 액티비티로부터 숨김을 당했을 때이다 - 화면의 전경에 있는 다른 앱이 반투명이거나 전체화면을 모두 점유하지 못할 때이다. 이 상황에서는 사용자의 입력을 받을 수 없고 어느 코드도 실행될 수 없다.

3. 멈춘(Stopped): 액티비티가 완전히 가려졌거나 화면에 전혀 보이지 않을 때이다. 백그라운에서 돌아가게 되고 이 멈춤 중에는 액티비티의 인스턴스와 모든 멤버 변수같은 상황 정보 보유되나 코드를 실행시킬 수는 없다.


앱 런처 액티비티의 명세(Specify Your App's Launcher Activity)

홈 스크린에서 앱 아이콘을 실행하면 런처(or 메인)로 앱티비티로 지정된 액티비티의 onCreate() 메소드가 실행시된다.(메니페스트 파일에 명시)


새로운 인스턴스 생성(Create a New Instance)

액티비티가 실행되면 새로운 Activity 인스턴스의 onCreate() 메소드를 실행시키고 사용자 인터페이스(XML 레이아웃 파일)를 정의하거나 맴버 변수 정의 혹은 UI의 환경설정 등을 할 수 있다.

onCreate() 메소드가 실행되고 바로 onStart() 메소드가 실행되어 화면이 보이게 되지만 또 바로 onResume()로를 호출되어 Resumed 상황이 되기 때문에 다른 상황 변화에 대해서 Started 상황이 컨트롤 할 필요는 없다.


액티비티 소멸(Destroy the Activity)

대부분의 경우 onDestroy() 메소드를 사용할 일이 없지만(자동으로 메모리 관리) 만약 액티비티가 onCreate() 메소드에서 백그라운드 스레드를 만들거나 롱런 자원을 가지고 있다면 이 자원들이 메모리 누수를 일이킬 수 있음으로 onDestroy() 메소드를 통해 이 자원들을 닫아줘야 한다.


그림 1에서 와 같이 onDestory() 메서드 호출 전 onPause(), onStop()가 먼저 이루어진다. 하지만 예외가 하나 이다. onCreate() 메소드에서 finish() 메서드를 콜했을 때이다. 일시적 결정권자로써 액티비티가 다른 액티비티를 실행시켰을 때 finish()를 호출할 수 있는데 이는 중간 과정 없이 onDestory() 메서드를 호출 한다.

Posted by Brian B. Lee
Programming/Android2013. 9. 29. 19:16

Android Development - Application Fundamentals (2/2)


메니페스트 파일(The Manifest File)

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


AndroidManifest.xml 파일을 읽음으로 다른 컨포넌트의 존재를 인지할 수 있다. 프로젝트 루트 디렉토리에 이 파일이 존재하며 앱이 사용하는 모든 컨포넌트는 이곳에 선언되어야 한다.


다음과 같은 컨포넌트 왜 다른 것들도 이곳에 선언된다

-  인터넷 접속이나 사용자 연락처 정보 접속같은  앱에 대한 요구 허용

- 앱이 사용하는 API으로 된 앱의 최소 버전 정보

- 카메라, 블루투스 서비스, 멀티 터치 등 앱에의해 사용되거나 요구되는 하드웨어, 소프트웨어 정보

- 구글 맵 라이브러리 같은 링크되어있는 앱에서 사용되는 API 라이브러리

- 기타 정보


컨포넌트 선언 (Declaring components)

- 액티비티: <activity>

- 서비스: <service>

- 브로드케스트 리시버: <receiver>

- 콘텐트 프로바이더: <provider>


액티비티, 서비스, 콘텐트 프로바이더는 메니페이스파일에 선언되어야하지만 브로드케스트 리시버는 이곳에 선언되어도 되고 아니면 코드에 BroadcastReceiver 추상클래스의 객체로 생성된 후 registerReceiver() 메서드로 시스템에 등록될 수 있다.


컨포넌트 선언 능력(Declaring component capabilities)

컨포넌트를 실행을 위해 Intent 객체를 인스턴스화 할때 직접 그 컨포너트를 명시할 수 있다. 그러나 Intent의 진정한 힘은 그 대상 컨포넌트를 숨기는 것이다. intent의 행동에서, 행동의 타입을 간략하게 정의하고 이 행동을 실행할 수 있는 기기의 컨포넌트를 시스템이 찾는것을 허용할 수 있다. intent에의해 명시된 행동을 실행할 수 있는 다수의 컨포넌트가 있다면, 사용자는 이중 하나를 고를 수 있다.


intent에 응하는 컨포넌트를 시스템이 인지할 수 있는 방법은 다른 앱이나 기기의 메니페스트 파일에 주어진 <intent-filter> 태그로 intent를 구별할 수 있다.


예를 들어 하나의 이메일 앱에서 새로운 메일을 작성하는 액티비티는 "send" intent를 응답하기 위해 Intent 필터를 메니페스트에 선언할 수 있다. 앱의 액티비티가 "send" 행동(ACTION_SEND)을 포함한 intent를 만들 수 있다. startActivity() 메소드를 실행시키면서 실행시킬때, 시스템이 이메일 앱의 "send" 액티비티를 찾고 이것을 시작할 수 있다.


나도 이걸 해석하면서 뭔말인지 모르겠어서 intent filter에 대해 검색해보았다. 결론적으로 선언방법으로 명시적/암시적 두가지 방법이 있다. 

1. 명시적 intent는 객체 인스턴스화 할때 타겟 컨포넌트를 인자로 선언하는 방법이고 

2. 암시적 intent는 메니페시트에 필터를 선언하여 intent를 받았을 때 어떤 컨포넌트를 실행할지 결정하는 방법이다.

더욱 자세한 사항은 검색 하시길~ 


앱 요구사항 선언(Declaring application requirements)

안드로이드에 만들어지는 많은 기기들이 존재하고 이 모든 기기가 똑 같은 기능을 제공하지 않는다. 앱이 필요로하는 기능의 결핍을 막기 위해, 메니페스트 파일에 기기와 소프트웨어의 요구사항을 명확하게 명시하는 것이 주용하다. 기기에 따라 대부분의 선언이 정보화 되며 Google Play같은 외부 서비스에서도  기기에서 앱을 찾기 위해 사용자에게 정보를 제공하기 위해 이 정보를 사용한다.


예를들어 만약 앱에서 카메라를 필요로 한다면 메니페스트에 이를 명시해야하고 이 명시를 보고 Google Play에서 이를 실행할 수 없는(Android 2.1 이하 혹은 카메라가 없는 기기)를 선별하여 인스톨이 가능하게 한다.


그러나 앱에서 카메라를 사용한다고 해서 이를 명시하는 것이 필수 요구사항은 아니지만 이에대한 결과에대해 체크해 보야한다.


다음은 중요한 명가지 기기 특성이다.

화면 사이즈와 농도(Screen size and density): <supports-screens>

입력 형태(Input configurations)/하드웨어 키보드 등: <uses-configuration>

기기 특정(Device features): <uses-feature>

플렛폼 버전(Platform Version): <uses-sdk>


다음 번에는 액티비티의 라이프 사이클(Managiing the Activity Lifecycle)에 대해 알아보겠다.

Posted by Brian B. Lee
Programming/Android2013. 9. 28. 21:14

Android Development - Application Fundamentals (1/2)


애플리케이션 컨포넌트 (Application Components)

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


오늘은 자바의 기본 컨포넌트들을 정리하겠다. (본 내용은 위의 안드로이드 개발자 싸이트에 내용을 요약한 것이다.)


안드로이드의 기본 구성으로 네가지 어플리케이션 컨포넌트 타입이 있다. 각 타입은 명확히 다른 목적을 가지며 라이프사이클(생성->소멸)을 가진다.


1. Activities: 하나의 액티비티는 사용자 인터페이스에서 하나의 화면을 나타낸다.

예를들어 Email 앱의 경우 아마도 새로운 메일 리스트를 보인다거나 메일 작성화면 메일을 읽는 화면등이 각각의 액티비티가 될 수 있다. 하지만 이런 각각의 앱티비티가 하나의 앱을 이루지만 각각은 독립적이다. 이렇게 어떤 앱이 다른 앱의  액티비티를 실행시킬수 도 있다.(다른 앱이 이를 허용하는 경우). 이 예는 카메라 앱에서 Email 앱으로 데이터를 정송하는 경우등을 들 수 있다.

액티비티는 Activity 크래스로부터 상속된 하위 클래스이다.

참조: http://developer.android.com/guide/components/activities.html


2. Services: 서비스는 백그라운드에서 동작하며 독작을 운영하거나 프로세스를 삭제하는 작업을 한다.

이 서비스는 사용자 인터페이스에 보이지 않는다. 예를 들어 사용자가 다른 앱으로 작업하는 동안 백그라운드에서 음악을 실행시킨다거나 사용자 화면 없이 네트웩을 통해 데이터를 주고 받을 수 있다. 다른 컨포넌트를 통해(액티비티 같은) 서비스를 실행시키거나 멈추는 서비스와의 상호작용을 할 수 있다.

서비스는 Service 추상 크래스로부터 상속된 하위 클래스이다.

참조: http://developer.android.com/guide/components/services.html


3. Content providers: 콘텐트 프로바이더는 애플리케이션 데이터를 공유한다.

아마 너는 파일 시스템을 통해 데이터를 SQLite  데이터 베이스라던지, 웹, 그 밖에 너가 접속할 수 있는 데이터 스토리지에 저장할 수 있을 것이다. 콜텐드 프로바이더를 통해 다른 앱들이 이런 데이터에 쿼리하거나 수정할 수 있다.(물론 콘텐트 프로바이더가 이를 허락하는 경우) 하나의 예로 컨턴트 프로바이더는 사용자의 연락처 정보를 제공할 수 있다. 이렇게 적당한 허용하에 어떠한 앱도 각 개인의 관한 정보를 읽거나 쓰는 쿼리를 컨턴트 프로바이더를 사용함으로써 이용할 수 있다.

컨텐트 프로바이더는 또한 공유되지 않는 개인 자원의 읽기 쓰기에 도 용이하다.

컴텐트 프로바이더는 ContentProvider 추상 클래스로부터 상속된 하위 클래스이다.

참조: http://developer.android.com/guide/topics/providers/content-providers.html


4. Broadcast receivers: 브로드케스트 리씨버는 시스템 전반의 브로드케스트 알림을 알린다.

많은 브로드케스트는 메인 시스템으로부터 시작된다. 예를들어 브로드케스트 알람은 화면 꺼짐, 베터리 낮음, 화면 쳅처같은 것이 될 수 있다. 앱 또한 브로디케스팅을 할 수 있는데 예를 들어 어떤 데이터가 다운로드되어 다른 앱들이 이를 사용할 수 있을때 이를 이용한다.

브로드케스트 리시버는 BroadcastReceiver 추상 클래스로부터 상속된 하위 클래스이며 각각의 브로드케스트는 Intent 객체로 전달 된다.


컨포넌트의 실행 (Activating Components)

컨포넌트 중 세가지(Activates, Services, Broadcast Receivers)의 경우 비동기적으로 Intent 객체에 의해 동작된다. Intent 객체는 실행 중 서로 다른 컨포넌트들을 묶는 역할을 한다.(쉽게 메신저 역할로 다른 컨포넌트들에게 요청할 수 있다.)


Intent 클래스의 객체는 특정 컨포넌트나 특정 타입의 컨포넌트를 실행시킬 메시지를 정의할 수 있다.


1. 액티비티와 서비스를 위해 화면을 보이거나 무언가를 전달하는 행동을 정의할 수 있다. 예를들어 intent가 웹페이지를 오픈하거나 이미지를 보이는 질의를 전달할 수 있다. 이경우 받은 액티비티가 이를 실행하고 또 결과로 intent를 반환할 수 있다. (예를들어 당신이 개인 연락처를 받고자할 때, 선택된 연락처의 URI정보를 intent를 통해 반환 받을 수 있다.)

Activity: startActivity(), startActivityForResult() 메서드에 intent 인자를 넘김으로 실행(새로운 할것리를 전달)

Service: startService(), bindService() 메서드에 intent 인자를 넘김으로 실행(새로운명령을 실행시키거나 계속 진행)

2. 브로트케스트 리씨버의 경우 intent가 브로드케스트 알림 정보를 정의 할 수 있다.

Broadcast Receiver:  Intent 클래스의 메소드 sendBroadcast(), sendOrderedBroadcast(), sendStickyBroadcast().


3. 마지막으로 컨텐트 프로바이더는 intent에 의해 실행되지 않는다. 이는 ContentResolver(추상클래스)로 부터 요청받았을 때 실행되어 진다. 컨텐트 리졸버는 모든 컨텐트 프로바이터의 트렌젝션을 핸들링한다.  제공자와 트렌젝션하는 컨텐트는 이를 필요로하지 않고 대신에 ContentResolver 객체의 메서드르 호출한다. 이것이 컨텐트 프로바이터와 컨텐트 요구 정보를 추상화하는 개층이 된다.(보안을 위한)

Content Providers: ContentResolver 클래스의 query() 사용.


다음 번에는 Manifest File에 대하여 알아보겠다.

Posted by Brian B. Lee