본문 바로가기
My Image
프로그래밍/Android

[Android] BroadCastReceiver(브로드캐스트리시버)

by Lim-Ky 2017. 6. 27.
반응형

이번 시간에는 브로드캐스트리시버에 대해서 알아보자..


BroadCastReceiver 는 4대 컴포넌트 중에 하나이다. 

BroadCastReceiver 의 역할은 단말기 안에서 이루어지는 수많은 일들을 대신해서 알려준다.

예를들어 배터리부족,SMS문자메시지,전화가온다거나 하는 일들을 방송알림 해준다.


BroadCastReceiver를 구현하기 위해 2가지 방법이 존재한다.

코드상에서 BroadCastReceiver를 등록하는 방법인 동적인 방법과

Manifest.xml에 <Receiver></Receiver>의 형태로 등록하는 정적인 방법이 존재한다.


1. 정적으로 Receiver 구현하기


먼저 정적인 방법을 소개한다..


앞서 말했듯이 Manifest.xml에 우선 BroadCastReceiver를 다음과 같이 등록하자!


나는 다음과 같이 폴더를 만들었기 때문에 receiver.MyBroadCastReceiver 형식으로 name을 선언했다.


또 BroadCastReceiver가 액션이벤트를 받도록<action> 태그를 등록했다.


<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<receiver android:name=".receiver.MyBroadCastReceiver">
<intent-filter>
<action android:name="com.example.limky.broadcastreceiver.gogo"></action>
</intent-filter>
</receiver>

이제 BroadCastReceiver 를 상속받아 onReceive()메서드를 오버라이딩한다.


onReceive()메서드는 intent-filter을 통해 걸러진 intent를 받아들이는 곳이다.


걸러진 intent의 액션값을 토스트로 띄우도록 코드를 짠다.


public class MyBroadCastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String actionName = intent.getAction();
Toast.makeText(context, "받은 액션 : "+actionName , Toast.LENGTH_SHORT).show();

}
}

마지막으로 sendBroadCast를 인위적으로 발생시켜 해당 인텐트가 


인텐트필터를 걸쳐 잘 걸러져서 BroadCastReceiver가 받는지 확인해보겠다.

public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

public void clickMethod(View v){
sendBroadcast(new Intent("com.example.limky.broadcastreceiver.gogo"));
}

}

확인 결과 onReceive()메서드가 intent를 받아 토스트 창을 띄웠다.


 





1. 동적으로 Receiver 구현하기


위 예제를 동적인 버전으로 구현해보겠다.


우선 Menifest.xml에 따로 receiver를 등록할 필요없이 MainActivity에서 모든 작업이 이루어진다.


1. 인텐트필터 생성 및 액션 등록

2. 브로드캐스트 익명클래스로 생성 및 구현

3. 브로드캐스트와 인텐트를 등록한다.

4. 등록한 브로드캐스를 종료한다.


정도로 요약할 수 있다. 코드를 쭈욱 보면서 이해하면 될 것 같다. 



public class MainActivity extends AppCompatActivity {

private final String BROADCAST_MESSAGE = "com.example.limky.broadcastreceiver.gogo";
private BroadcastReceiver mReceiver = null;
private int number = 0;

@Override
protected void onResume() {
super.onResume();
registerReceiver();
}

@Override
protected void onPause() {
super.onPause();
unregisterReceiver();

}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
/** 브로드 캐스트를 발생시킨다. **/
public void clickMethod(View v){
/** 1. 전달할 메세지를 담은 인텐트 생성
* 2. DATA를 잘 전달받는지 확인할 수 있게 Key, value 넣기
* 3. sendBroadcast(intent); 메서드를 이용해서 전달할 intent를 넣고, 브로드캐스트한다. */

Intent intent = new Intent(BROADCAST_MESSAGE);
intent.putExtra("value",number);
sendBroadcast(intent);
number++;

}
/** 동적으로(코드상으로) 브로드 캐스트를 등록한다. **/
private void registerReceiver(){
/** 1. intent filter를 만든다
* 2. intent filter에 action을 추가한다.
* 3. BroadCastReceiver를 익명클래스로 구현한다.
* 4. intent filter와 BroadCastReceiver를 등록한다.
* */
if(mReceiver != null) return;

final IntentFilter theFilter = new IntentFilter();
theFilter.addAction(BROADCAST_MESSAGE);

this.mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int receviedData = intent.getIntExtra("value",0);
if(intent.getAction().equals(BROADCAST_MESSAGE)){
Toast.makeText(context, "recevied Data : "+receviedData, Toast.LENGTH_SHORT).show();
}
}
};

this.registerReceiver(this.mReceiver, theFilter);

}

/** 동적으로(코드상으로) 브로드 캐스트를 종료한다. **/
private void unregisterReceiver() {
if(mReceiver != null){
this.unregisterReceiver(mReceiver);
mReceiver = null;
}

}


}


결과는 다음과 같다. 리시버가 받는 data값을 sendBroadCast할 때마다 data 값을 1씩 증가시켰기 때문에 

버튼을 클릭할 때마다 data가 증가한다.




정적, 동적 구현방법 모두 알아보았다.



3. 정적,동적 브로드캐스트리시버의 차이점


이제 어떤 차이가 있는지 알아보자. 아래 사이트에 차이점을 잘 기술해놓았다. 참고하자


http://cafe.daum.net/_c21_/bbs_search_read?grpid=1MWA2&fldid=aAfL&datanum=102


요약을 하자면...


정적 리시버는 한번등록하면, 쉽게 해체하기 어렵기 때문에 계속적으로 유지가 되는 경향이 있다. 

하지만 동적 리시버는 등록과 해체가 유연하기 때문에 등록/해체가 빈번하게 일어나는 경우엔 유리하다.


또 동적리시버는 정적리시버와 달리 자신을 등록한 해당 컴포넌트의 생명주기에 영향을 받는다.

그러면서 동시에 해당컴포넌트에 동적리시버를 구현했기 때문에 컴포넌트 안에 있는 변수와 메서드에 대한 

접근이 유연하다.


하지만 주의해야할 점도 있다. 동적리시버는 등록과 해체를 자유자재로 할 수 있기 때문에

필요할때만 등록하고 일을 다하면 꼭 해체시켜줘야지 불필요하게 중복으로 리시버를 등록해서는 안된다.

(또 Recevier에서는 bindService가 허용되지 않는다.)


여러개의 브로드캐스트를 등록한 경우 순차적으로 한개씩 브로드캐스트가 작업을 하기 때문에 마지막에 일처리를 하는 브로드캐스트는 

작업지연이 심해질 수 있다. 이는 ANR을 발생시킬 여지를 주기 때문에 다중 브로드캐스트 작업시 ANR에 대한 가능성을 염두해서 코딩해야한다.


마지막으로 리시버에서 너무 많은 작업, 시간이 오래걸리는 작업을 시키지말자. 만약 리시버로 인한

처리지연시간이 길어질 경우 메인스레드(UIThread)의 딜레이를 안드로이드 시스템에서 가만두고 볼 수 없기 때문에

ANR을 발생시킨다. 따라서 리시버에는 간단한 일을 처리하도록하고, 정 일이 많다면 작업스레드를 별도로 생성해서 처리하도록 하자.






반응형

댓글