작업 상태 보고

이 가이드에서는 백그라운드 서비스에서 실행된 작업 요청의 상태를 요청을 보낸 구성요소에 보고하는 방법을 설명합니다. 예를 들어 Activity 객체의 UI에 요청 상태를 보고할 수 있습니다. 상태를 주고받는 데 권장되는 방법은 브로드캐스트 Intent 객체를 자체 앱의 구성요소로 제한하는 LocalBroadcastManager를 사용하는 것입니다.

JobIntentService에서 상태 보고

JobIntentService의 작업 요청 상태를 다른 구성요소로 보내려면 먼저 확장 데이터에 상태를 포함하는 Intent를 만듭니다. 옵션으로 이 Intent에 작업과 데이터 URI를 추가할 수 있습니다.

그런 다음, LocalBroadcastManager.sendBroadcast()를 호출하여 Intent를 전송합니다. 이렇게 하면 이를 수신하도록 등록된 애플리케이션의 모든 구성요소에 Intent이 전송됩니다. LocalBroadcastManager의 인스턴스를 가져오려면 getInstance()를 호출합니다.

예:

Kotlin

...
// Defines a custom Intent action
const val BROADCAST_ACTION = "com.example.android.threadsample.BROADCAST"
...
// Defines the key for the status "extra" in an Intent
const val EXTENDED_DATA_STATUS = "com.example.android.threadsample.STATUS"
...
class RSSPullService : JobIntentService() {
    ...
    /*
     * Creates a new Intent containing a Uri object
     * BROADCAST_ACTION is a custom Intent action
     */
    val localIntent = Intent(BROADCAST_ACTION).apply {
        // Puts the status into the Intent
        putExtra(EXTENDED_DATA_STATUS, status)
    }
    // Broadcasts the Intent to receivers in this app.
    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent)
    ...
}

Java

public final class Constants {
    ...
    // Defines a custom Intent action
    public static final String BROADCAST_ACTION =
        "com.example.android.threadsample.BROADCAST";
    ...
    // Defines the key for the status "extra" in an Intent
    public static final String EXTENDED_DATA_STATUS =
        "com.example.android.threadsample.STATUS";
    ...
}
public class RSSPullService extends JobIntentService {
...
    /*
     * Creates a new Intent containing a Uri object
     * BROADCAST_ACTION is a custom Intent action
     */
    Intent localIntent =
            new Intent(Constants.BROADCAST_ACTION)
            // Puts the status into the Intent
            .putExtra(Constants.EXTENDED_DATA_STATUS, status);
    // Broadcasts the Intent to receivers in this app.
    LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
...
}

다음 단계는 원래 작업 요청을 전송한 구성요소에서 수신 브로드캐스트 Intent 객체를 처리하는 것입니다.

JobIntentService에서 상태 브로드캐스트 수신

브로드캐스트 Intent 객체를 수신하려면 BroadcastReceiver의 서브클래스를 사용합니다. 서브클래스에서 LocalBroadcastManagerIntent를 수신하면 호출하는 BroadcastReceiver.onReceive() 콜백 메서드를 구현합니다. LocalBroadcastManager는 수신 IntentBroadcastReceiver.onReceive()에 전달합니다.

예:

Kotlin

// Broadcast receiver for receiving status updates from the IntentService.
private class DownloadStateReceiver : BroadcastReceiver() {

    override fun onReceive(context: Context, intent: Intent) {
        ...
        /*
         * Handle Intents here.
         */
        ...
    }
}

Java

// Broadcast receiver for receiving status updates from the IntentService.
private class DownloadStateReceiver extends BroadcastReceiver
{
    // Called when the BroadcastReceiver gets an Intent it's registered to receive
    @Override
    public void onReceive(Context context, Intent intent) {
...
        /*
         * Handle Intents here.
         */
...
    }
}

BroadcastReceiver를 정의한 후에는 특정 작업, 카테고리 및 데이터와 일치하는 필터를 정의할 수 있습니다. 이렇게 하려면 IntentFilter를 만듭니다. 이 첫 번째 스니펫은 필터 정의 방법을 보여줍니다.

Kotlin

// Class that displays photos
class DisplayActivity : FragmentActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {
        ...
        super.onCreate(savedInstanceState)
        ...
        // The filter's action is BROADCAST_ACTION
        var statusIntentFilter = IntentFilter(BROADCAST_ACTION).apply {
            // Adds a data filter for the HTTP scheme
            addDataScheme("http")
        }
        ...

Java

// Class that displays photos
public class DisplayActivity extends FragmentActivity {
    ...
    public void onCreate(Bundle stateBundle) {
        ...
        super.onCreate(stateBundle);
        ...
        // The filter's action is BROADCAST_ACTION
        IntentFilter statusIntentFilter = new IntentFilter(
                Constants.BROADCAST_ACTION);

        // Adds a data filter for the HTTP scheme
        statusIntentFilter.addDataScheme("http");
        ...

BroadcastReceiverIntentFilter를 시스템에 등록하려면 LocalBroadcastManager의 인스턴스를 가져와 registerReceiver() 메서드를 호출합니다. 다음 스니펫은 BroadcastReceiverIntentFilter를 등록하는 방법을 보여줍니다.

Kotlin

        // Instantiates a new DownloadStateReceiver
        val downloadStateReceiver = DownloadStateReceiver()
        // Registers the DownloadStateReceiver and its intent filters
        LocalBroadcastManager.getInstance(this)
                .registerReceiver(downloadStateReceiver, statusIntentFilter)
        ...

Java

        // Instantiates a new DownloadStateReceiver
        DownloadStateReceiver downloadStateReceiver =
                new DownloadStateReceiver();
        // Registers the DownloadStateReceiver and its intent filters
        LocalBroadcastManager.getInstance(this).registerReceiver(
                downloadStateReceiver,
                statusIntentFilter);
        ...

단일 BroadcastReceiver는 각각 자체 작업을 가진 둘 이상의 브로드캐스트 Intent 객체 유형을 처리할 수 있습니다. 이 기능을 사용하면 각 작업에 별도의 BroadcastReceiver를 정의하지 않고도 작업별로 다른 코드를 실행할 수 있습니다. 동일한 BroadcastReceiver에 다른 IntentFilter를 정의하려면 IntentFilter를 만들고 registerReceiver() 호출을 반복합니다. 예:

Kotlin

        /*
         * Instantiates a new action filter.
         * No data filter is needed.
         */
        statusIntentFilter = IntentFilter(ACTION_ZOOM_IMAGE)
        // Registers the receiver with the new filter
        LocalBroadcastManager.getInstance(this)
                .registerReceiver(downloadStateReceiver, statusIntentFilter)

Java

        /*
         * Instantiates a new action filter.
         * No data filter is needed.
         */
        statusIntentFilter = new IntentFilter(Constants.ACTION_ZOOM_IMAGE);
        // Registers the receiver with the new filter
        LocalBroadcastManager.getInstance(this).registerReceiver(
                downloadStateReceiver,
                statusIntentFilter);

브로드캐스트 Intent를 전송해도 Activity가 시작되거나 재개되지 않습니다. ActivityBroadcastReceiver는 앱이 백그라운드에 있을 때도 Intent 객체를 수신하고 처리하지만 앱을 포그라운드로 강제하지 않습니다. 앱이 표시되지 않는 동안 백그라운드에서 발생한 이벤트에 관해 사용자에게 알리려면 Notification를 사용하세요. 수신되는 브로드캐스트 Intent에 관한 응답으로 Activity를 시작하면 안 됩니다.