본문 바로가기
Basics/Android

[안드로이드의 신] 안드로이드 컴포넌트

by Z_dol 2018. 12. 8.

1.  액티비티 생명주기

a. 액티비티 처음 시작시 onCreate 하고 onStart 하고 onResume.

b. 액티비티에서 나가면 onPause 하고 onStop하고 onDestory

c. 다시 액티비티 시작하면 a로 돌아간다.

d. 메인 화면으로 나가면 onPause 하고 onStop한다.

e. 다시 앱으로 들어가면 onRestart하고 onStart하고 onResume


2. 데몬 서비스 생명주기

*데몬이란 멀티태스킹 운영체제에서 데몬은 사용자가 직접적으로 제어하지 않고, 백그라운드에서 돌면서 여러 작업을 하는 프로그램을 말한다.

a. onStartCommand에서 반환 결과 값

START_STICKY

 서비스 강제 종료시 시스템이 다시 서비스를 재시작.

 이때 intent의 값은 null로 초기화시켜서 재시작한다.

 **참고보기.
 이후 시스템에 의해 서비스가 강제 종료 되면, 기존 전달 받은 intent는 

 null로 초기화 된 상태로 onStartCommand()에 전달된다.

START_NOT_STICKY 

 강제 동료된 서비스가 재시작하지 않는다.

 시스템에 의해 강제 종료되어도 영향을 받지 않는 작업을 진행할 때 사용한다.

START_REDELIVER_INTENT 

 서비스가 종료되었을 경우 시스템에서 다시 서비스를 재시작하지만 intent 값은 그대로 유지시킨다.

** 서비스 실행시 intent에 정보를 담아서 서비스에 전달하면, 서비스의 onStartCommand()를 통해서 intent 정보를 받게된다

b. onCreate  - onStartCommand - onDestory 이것 반복

c. 종료 방식

외부 종료. :  stopService(intent)
내부 종료 :  stopSelf()


3. 원격 서비스

a. 정의 : 프로세스 간의 통신(IPG)을 가능하게 하는 것. 클라이언트/서버 구조로 이해하면 쉽다. 작업에 대한 처리 결과를 받을 수 있다.(데몬은 받을 수 없음)

b. 전체 흐름

* 용어 정리

IPC : 각 프로세스는 메모리와 CPU를 공유하고 있을 뿐이지 독립된 일을 하며 상호간섭하지 않고 간섭할 수 없다. 하지만 필요에 따라 프로세스 간에 정보를 교환해야 할 경우가 있다. 이때 프로세스가 상호 통신을 하며 정보를 교환하는 방법을 IPC라고 한다. 종류에는 Shared Memoory, Message passing, Sockets, Pipe, Remote Procedure Call(RPC). 안드로이드 원격 서비스는 RPC를 사용한다.

RPC : 하나의 프로세스에서 다른 프로세스의 API를 호출하는 방법으로 Stub을 이용한다.

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

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

Marshaling/UnMarshaling : MArshaling은 클라이언트가 원격지(서로 다른 프로세스)의 메서드를 호출 시 서버에 넘겨지는 인자, 원격지 함수의 린턴 값들을 프로그래밍 인터페이스에 맞도록 그 데이터를 조직화하고, 미리 정해진 다른 형식으로 변환하는 과정을 말한다. UnMarshaling은 반대로 전송받은 데이터를 원래의 형태로 복원하는 과정을 말한다.

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


c. 필요 절차

[RemoteService] :  AIDL 파일을 생성 -> 원격 시비스를 만들기 -> AndroidManifest.xml 파일에 원격 서비스 등록

[Client] : AIDL 파일을 생성 -> Stub 생성 여부 확인 ->  원격 서비스 연결 -> 원격 메서드 호출 -> 원격 서비스 연결 종료


**primitive Type: 자바의 데이터 타입은 Primitive Type(Internal: byte, short, int, long, char  Float point: float, double Boolean:  boolean)와 Reference Type(class, interface, array, enum) 으로 분류


실습 실패! App, remoteservice 모듈 다시 해보기



4. 인텐트와 인텐트 필터

a. 정의 : 인텐트는 안드로이드 컴포넌트 간에 데이터 전달 또는 컴포넌트 실행을 위해 사용

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

액티비티 호출은 호출되는 대상의 클래스명이 들어가지만 전화 걸기, 문자보내기 와 같은 것들은 액션명이 들어간다.

액션명은 동일한 기능을 사용하는 앱이 있으면 화면에 보여주고 사용자가 원하는 앱을 선택하여 사용할 수 있다록 한다.

반대로 액티비티 호출과 같이 클래스명을 지정하면 지정된 클래스명의 액티비티만 실행된다.

b. 명시적 인텐트, 암시적 인텐트

명시적 인텐트 :  인텐트를 받는 대상이 클래스명으로 지정하여 대상을 명시하는 것

암시적 인텐트 : 받는 대상을 명시하지 않고 대신 특정 액션명을 지정하여 인텐트를 전달하는 것. 

일반적으로 앱 내에서 컴포넌트간의 호출은 명시적(클래스명) 


* URI : Uniform Resource Identifier. 안드로이드에서 전화, 이메일, 문자, 웹 브라우저를 실행할 때 사용된다. 즉 어떤 자원에 접근하기 위한 유일한 주소라고 할 수 있다. ex) tel, smsto, mailto, http


c. 인텐트 필터 : 전달되는 인텐트 정보 중에서 필요한 인텐트만을 선택해서 받을 수 있는 것을 말한다. ex) gmail, 이메일 두가지가 있을 때 선택지가 나옴


5. 브로드캐스트, 리시버

a. 정의 : 브로드캐스트가 방송국과 마찬가지로 특정 이벤트를 발생하면 리시버는 채널을 맞추는 작업처럼 특정 이벤트를 받을 수 있도록 등록을 한다. 따라서 등록된 앱에 한해서 해당 브로드캐스트 정보를 수신할 수 있다.

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

c. 정적 등록과 동적 등록


 

 정적 등록

동적 등록 

정의 

 

   리시버를 AndroidManifest.xml에 등록하는 것. 

   즉 앱이 설치되고 실행되는 순간부터 삭제되는 순간까지  모두 받게 되는 것

   (단 정적등록 사용이 되는 것은 제한이 되어 있다.)


    

    자바에 BroadcastReceiver 클래스를 생성하고 

    IntentFilter 클래스를 만들고 브로드캐스트 정보를 추가하고 리시버에 등록

    (단 동적 등록 또한 모든 브로드캐스트를 동적 등록 할 수 없다. 

    예로 배터리 상태 등)


 예제

 

[ AndroidManifest.xml ]

<receiver android:name="브로드캐스트관련 자바파일명"

      <intent-filter>

           <action android:name="android.intent.action.PACKAGE_ADDED"/>

     </intent-filter>

</receiver>


[packagereceiver.java]

public class packagereceiver extends BroadcastReceiver{

     @Override

     public void onReceive(Context context, Intent intent){

           if(intent.getAction().equals("android.intent.action.PACKAGE_ADDED"){

                //내용 

          }

     }

}


[MainActivity.java] 

public class MainActivity extends AppcompatActivity{

     private BroadcastReceiver screenReceiver = null;

     private IntentFilter screenFilter = null;


     @Override

     protected void onCreate(Buncle svedInstance){

          super.onCreate(savedInstance);

          setContentView(R.layout.activity_main);

          screenReceiver = new BroadcastReceiver(){

              @Override

              public void onReceive(Context context, Intent intent){

                   if(intent.getAction().equals("Intent.ACTION_SCREEN_ON"){

                   //내용

                   } //end if

              }//end onReceive

          };  //end BroadCastReceiver

          screenFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);

          screenFilter.addAction(다른 액션명);

          registerReceiver(screenReceiver, screenFilter);

      } // end onCreate


     @Override

     pubic void onDestory(){

          super.onDestory();

          if(null != screenReceiver)

                  unregisterReceiver(screenFilter);

     } // end onDestroy

}


6. 컨텐트 프로바이더

a. 정의 : 앱 간에 데이터 공유를 위해 사용된다. 기본적으로 데이터의 추가, 삭제, 업데이트, 조회 등의 기능을 제공한다. 주로 데이터베이스르 ㄹ사용하는 대용량 데이터를 공유하기 위한 목적이지만 꼭 데이터베이스가 아니어도 된다.

b. 구조


[Provider] : 데이터 공유를 제공하기 위해서는 ContentProvider 클래스를 상속받는 클래스를 반드시 만들어야한다. -> 그 안 onCreate에서 데이터베이스 생성과 테이블을 DBHandler를 통해 만든다. 데이터 추가, 삭제, 업데이트, 조회 시 구분하기 위해 **URI 를 사용한다.

**

Content://com.test.contentprovier(패키지명)/path/id

prefix: 컨텐트 프로바이더를 사용한다는 고정적인 스키마

Authority: 컨텐트 프로바이더 구분하기 위한 고유이름. 이를 사용하기 위해 manifest에 <provider> 엘리먼트에 authority속성과 동일한 내용을 추가해야 함.

path: 데이터베이스 같은 경우 DB 테이블을 의미. 데이터의 경로

id: path 안의 특정 레코드를 참조할 경우 사용

'Basics > Android' 카테고리의 다른 글

[안드로이드의 신] 안드로이드 프로세스와 스레드  (0) 2018.12.16