דיווח על סטטוס העבודה

במדריך הזה מוסבר איך לדווח על הסטטוס של בקשת עבודה שפועלת בשירות ברקע לרכיב ששלח את הבקשה. כך אפשר, לדוגמה, לדווח על הסטטוס של הבקשה בממשק המשתמש של אובייקט Activity. הדרך המומלצת לשלוח הוא להשתמש ב-LocalBroadcastManager, מגביל את השידור של Intent אובייקטים לרכיבים באפליקציה שלך.

דיווח על סטטוס מ-JobIntentService

כדי לשלוח את הסטטוס של בקשת עבודה ב JobIntentService לאפליקציה אחרת רכיבים, קודם כול צריך ליצור Intent שמכיל את הסטטוס נתונים מורחבים. יש אפשרות להוסיף URI של פעולה ו-URI של נתונים Intent

לאחר מכן, שולחים את Intent על ידי התקשרות למספר LocalBroadcastManager.sendBroadcast(). הפעולה הזו שולחת את 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. בתת-הסוג, מטמיעים את השיטה של הקריאה החוזרת (callback) BroadcastReceiver.onReceive(), ש-LocalBroadcastManager מפעילה כשהיא מקבלת Intent. LocalBroadcastManager מעביר את Intent הנכנס אל BroadcastReceiver.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");
        ...

כדי לרשום את BroadcastReceiver ואת IntentFilter במערכת, צריך לקבל מכונה של LocalBroadcastManager ולקרוא ל-method‏ registerReceiver() שלה. קטע הקוד הבא מראה איך לרשום את BroadcastReceiver וגם IntentFilter:

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 נפרד לכל פעולה. כדי להגדיר IntentFilter לאותו מחיר BroadcastReceiver, יוצרים את 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. BroadcastReceiver של Activity מקבל ומעבד Intent אובייקטים באופן שווה כשהאפליקציה פועלת ברקע, אבל לא כפויה את האפליקציה לעבור לקדמת התמונה. אם רוצים להודיע למשתמש על אירוע שהתרחש ברקע בזמן שהאפליקציה לא הייתה גלויה, משתמשים ב-Notification. לעולם לא להתחיל Activity בתגובה לשידור נכנס Intent