گزارش وضعیت کار

این راهنما به شما نشان می‌دهد که چگونه وضعیت اجرای درخواست کار را در سرویس پس‌زمینه‌ای به مؤلفه‌ای که درخواست را ارسال کرده است گزارش دهید. این کار به شما امکان می‌دهد، برای مثال، وضعیت درخواست را در واسط کاربر شیء Activity گزارش کنید. روش توصیه‌شده برای ارسال و دریافت وضعیت استفاده از LocalBroadcastManager است که اشیاء Intent همه‌فرستی را به مؤلفه‌های موجود در برنامه خودتان محدود می‌کند.

گزارش کردن وضعیت از JobIntentService

برای ارسال وضعیت درخواست کار در JobIntentService به دیگر مؤلفه‌ها، ابتدا Intent ایجاد کنید که حاوی وضعیت در داده‌های گسترش‌یافته آن باشد. به‌عنوان یک گزینه، می‌توانید کنش و شناسه منبع یکسان داده به این Intent اضافه کنید.

سپس، Intent را با تماس گرفتن با LocalBroadcastManager.sendBroadcast() ارسال کنید. این کار Intent را به هر مؤلفه‌ای در برنامه‌تان که برای دریافت آن ثبت‌نام کرده است ارسال می‌کند. برای دریافت نمونه‌ای از LocalBroadcastManager، getInstance() را فراخوانی کنید.

برای مثال:

کاتلین

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

جاوا

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

The next step is to handle the incoming broadcast Intent objects in the component that sent the original work request.

دریافت پخش وضعیت از JobIntentService

برای دریافت اشیاء Intent همه‌فرستی، از زیرکلاس BroadcastReceiver استفاده کنید. در زیرکلاس، روش فراخوانی برگشتی BroadcastReceiver.onReceive() را پیاده‌سازی کنید، که LocalBroadcastManager هنگام دریافت Intent آن را فراخوانی می‌کند. LocalBroadcastManager Intent ورودی را به BroadcastReceiver.onReceive() منتقل می‌کند.

برای مثال:

کاتلین

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

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

جاوا

// 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 ایجاد کنید. این قطعه کد اول نحوه تعریف فیلتر را نشان می‌دهد:

کاتلین

// 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")
        }
        ...

جاوا

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

برای ثبت BroadcastReceiver و IntentFilter در سیستم، نمونه‌ای از LocalBroadcastManager را دریافت کنید و روش registerReceiver() آن را فراخوانی کنید. قطعه کد بعدی نحوه ثبت BroadcastReceiver و IntentFilter آن را نشان می‌دهد:

کاتلین

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

جاوا

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

یک BroadcastReceiver می‌تواند بیش‌از یک نوع شیء همه‌فرستی Intent را مدیریت کند که هرکدام کنش خاص خود را دارند. این ویژگی به شما امکان می‌دهد کد متفاوتی را برای هر کنش اجرا کنید، بدون اینکه لازم باشد BroadcastReceiver جداگانه‌ای برای هر کنش تعریف کنید. برای تعریف کردن IntentFilter دیگری برای همان BroadcastReceiver، IntentFilter را ایجاد کنید و تماس با registerReceiver() را تکرار کنید. برای مثال:

کاتلین

        /*
         * 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)

جاوا

        /*
         * 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 نمی‌شود. BroadcastReceiver برای Activity اشیای Intent را دریافت و پردازش می‌کند، حتی وقتی برنامه‌تان در پس‌زمینه باشد، اما برنامه‌تان را مجبور نمی‌کند به پیش‌زمینه بیاید. اگر می‌خواهید کاربر را از رویدادی مطلع کنید که در پس‌زمینه اتفاق افتاده است درحالی‌که برنامه‌تان نمایان نبوده است، از Notification استفاده کنید. هرگز Activity را در پاسخ به Intent همه‌فرستی ورودی شروع نکنید.