Broadcast receivers

똘이주인·2021년 7월 27일
0
  • 안드로이드 4대 컴포넌트 중 1개
  • 각종 앱에서 발생하는 방송(이벤트)을 캐치 후 리시버로 처리할 수 있도록 해준다.
    1. 방송하기 -> 2. 수신하기(방송에 대한 처리), 두 개가 하나의 사이클로 동작된다.

Receiver종류

정적 리시버

  • 한번 등록되면 해제할 수 없다.
  • 메니페스트에 리시버를 등록하는 방식으로 정적리시버를 등록한다.
  • 해당 앱이 설치될때 자동으로 등록된다.

동적 리시버

  • 등록과 해제가 자유롭다.
  • 메니페스트에 등록하지않고 소스상에 등록을 한다.

리시버의 동작 제한(인텐트 플래그를 통한)

FLAG_EXCLUDE_STOPPED_PACKAGES

  • 앱이 한번이라도 실행됬을때만 리시버가 동작할 수 있도록 해준다.
  • API 12 이후로는 이 플래그는 기본으로 설정된다.

FLAG_INCLUDE_STOPPED_PACKAGES

  • 한번도 실해되지 않은 앱이라도 리시버가 동작하게 해준다.

FLAG_RECEIVER_REGISTERD_ONLY

  • 오직 동적리시버만 방송받을 수 있도록 해준다.

FLAG_RECEIVER_REPLACE_PENDING

  • 동일한 액션으로 중복해서 방송하는 경우 중복된 방송을 제거해준다.

리시버 동작시간 제한

리시버에서도 액티비티와 마찬가지로 작업시간이 제한되어있다. (메인스레드에서 동작하므로)

백그라운드 리시버 : 60초

포그라운드 리시버: 10초

리시버 호출 및 우선순위

  • 정적리시버는 절대 동시에 실행되지 않고 한개씩 처리한다.
  • 정적리시버는 앱이 먼저 설치된 우선순위로 실행된다.
  • 동적리시버는 동시에 실행된다.(우선순위가 중요하지않다.)
  • 동적리시버는 리시버가 작성된 컴포넌트가 종료되면 동작하지 않는다.(사실 onDestroy()함수에 unregister(receiver)를 통해서 리시버를 해제하지 않으면 동작하는데 그러면 메모리 누수가 발행하므로 꼭 해준다)
  • 방송할때 인텐트필터의 setPriority(1)함수로 우선순위를 조작할 수 있다. (클수록 우선, 동적리시버는 우선순위가 중요하지않음)
  • 정적리시버의 우선순위는 메니페스트의 인텐트필터요소에서만 설정가능하다. ( .. )
  • sendBroadcast()대신 sendOrderBroadcast()를 사용하면 동적리시버에서도 우선순위를 적용해서 처리할 수 있다.
  • setPackage()함수로 원하는 패키지의 리시버만 동작하도록 방송할 수 있다.

정적리시버 등록 및 사용 예

1. TestReceiver.java 클래스 작성

public class TestReceiver extends BroadcastReceiver {
		
		@Override
		public void onReceive(Context context, Intent intent) {
				Log.i("리시버알림","라이트 온");
				Toast.makeText(context, "Light On !!", Toast.LENGTH_SHORT).show();
		}
}

//-----------------------------------------------------------------------------

2. 메니페스트에 TestReceiver 등록

<?xml version="1.0" encoding="utf-8"?>
<manifest>

    <application>

        ...

        <receiver android:name=".TestReceiver">
            <intent-filter> <!--오래오 이전버전에서는 이렇게 해야됨-->
                <action android:name="com.test.action.TEST"/>
                <action android:name="android.intent.action.SCREEN_ON"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>

//-----------------------------------------------------------------------------

3. 액티비티에서 호출

@Override
protected void onCreate(Bundle savedInstanceState) {

		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		Intent intent = new Intent();
		intent.setAction("test.com.action.TEST");
		sendBroadcast(intent);
}
  1. 동작설명

  2. 위의 3번의 액티비티 화면의 앱을 켜면 방송(Broadcast)을 특정액션(test.com.action.TEST)으로 한다.

  3. 메니페스트에 등록한 정적리시버가 test.com.action.TEST의 액션을 포함하고 있으므로 4-1에서 방송을 리시버가 캐치해서 실행한다.

  4. Light On !! 이란 토스트팝업이 뜬다.

  5. 또한 2번의 메니페스트에 android.intent.action.SCREEN_ON 액션도 설정했으므로 휴대폰 화면을 껐다 켜도 이 리시버가 동작한다.

동적리시버 등록 및 사용 예

동적리시버는 메니페스트에 리시버를 등록해놓지 않는다.

1. 동적리시버 생성 및 등록
BroadcastReceiver receiver = null;

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // 인텐트 필터 설정
    IntentFilter intentFilter = new IntentFilter();
    intentFilter.addAction("test.com.action.TEST");

    // 동적리시버 생성
    receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context, "Light On !!", Toast.LENGTH_SHORT).show();
        }
    };
    // 위에서 설정한 인텐트필터+리시버정보로 리시버 등록
    registerReceiver(receiver, intentFilter);

} 

//-----------------------------------------------------------------------------

2. 동적으로 등록한 리시버 호출

Intent intent = new Intent();
intent.setAction("test.com.action.TEST");
sendBroadcast(intent);

동작은 정적리시버 예제와 동일하게 동작한다.

0개의 댓글