Báo cáo trạng thái công việc

Hướng dẫn này chỉ cho bạn cách báo cáo trạng thái của một yêu cầu công việc chạy trong dịch vụ nền cho thành phần đã gửi yêu cầu. Ví dụ: thao tác này cho phép bạn báo cáo trạng thái của yêu cầu trong giao diện người dùng của đối tượng Activity. Bạn nên sử dụng cách gửi và Nhận trạng thái là sử dụng LocalBroadcastManager, giới hạn việc truyền tin đối tượng Intent cho các thành phần trong ứng dụng của riêng bạn.

Báo cáo trạng thái qua JobIntentService

Để gửi trạng thái của yêu cầu công việc trong JobIntentService đến các thành phần khác, trước tiên, hãy tạo một Intent chứa trạng thái trong dữ liệu mở rộng. Bạn có thể thêm một hành động và URI dữ liệu vào Intent này nếu muốn.

Tiếp theo, hãy gửi Intent bằng cách gọi LocalBroadcastManager.sendBroadcast(). Thao tác này sẽ gửi Intent đến bất kỳ trong ứng dụng của bạn mà đã đăng ký nhận. Để nhận một thực thể của LocalBroadcastManager, hãy gọi getInstance().

Ví dụ:

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);
...
}

Bước tiếp theo là xử lý các đối tượng Intent truyền tin đến trong thành phần đã gửi yêu cầu công việc ban đầu.

Nhận thông báo trạng thái từ JobIntentService

Để nhận đối tượng Intent truyền tin, hãy sử dụng một lớp con của BroadcastReceiver. Trong lớp con, hãy triển khai phương thức Gọi lại BroadcastReceiver.onReceive()LocalBroadcastManager gọi khi nhận được Intent. LocalBroadcastManager truyền Intent đến đến BroadcastReceiver.onReceive().

Ví dụ:

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.
         */
...
    }
}

Sau khi xác định BroadcastReceiver, bạn có thể xác định các bộ lọc cho phù hợp với các hành động, danh mục và dữ liệu cụ thể. Để thực hiện việc này, hãy tạo một IntentFilter. Đoạn mã đầu tiên này minh hoạ cách xác định bộ lọc:

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");
        ...

Để đăng ký BroadcastReceiverIntentFilter bằng hệ thống, hãy lấy một thực thể của LocalBroadcastManager và gọi registerReceiver() . Đoạn mã tiếp theo này cho biết cách đăng ký BroadcastReceiverIntentFilter của tài khoản:

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);
        ...

Một BroadcastReceiver có thể xử lý nhiều loại thông báo truyền tin Đối tượng Intent, mỗi đối tượng có một thao tác riêng. Tính năng này cho phép bạn chạy mã khác nhau cho từng hành động mà không phải xác định một mã BroadcastReceiver cho mỗi hành động. Để xác định một IntentFilter khác cho cùng một BroadcastReceiver, hãy tạo IntentFilter và lặp lại lệnh gọi đến registerReceiver(). Ví dụ:

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);

Việc gửi thông báo truyền tin Intent sẽ không bắt đầu hoặc tiếp tục Activity. BroadcastReceiver cho một Activity nhận và xử lý đối tượng Intent ngay cả khi khi ứng dụng chạy ở chế độ nền, nhưng không buộc ứng dụng phải chạy ở nền trước. Nếu bạn thông báo cho người dùng về một sự kiện đã xảy ra trong nền khi ứng dụng của bạn không hiển thị, hãy sử dụng Notification. Không bao giờ bắt đầu Activity để phản hồi một thông báo truyền đến Intent.