2016-07-28 26 views
4

Ich habe einen jobscheduler, der onStartjob von Jobservice auslöst. In onStartJob starte ich einen Intentservice, um die Arbeit zu erledigen. Nachdem die Arbeit erledigt ist, möchte ich, dass intentservice einen Rückruf zum Jobservice durchführt, damit onjobfinished aufgerufen werden kann. Wie kann ich einen Rückruf zu JobService durchführen?Rückruf zum Jobservice von intentservcie

Antwort

3

Sie können BroadcastReceiver erstellen und in Ihrer Jobservice, in onStartJob() Methode, mit einer ACTION-Konstante (zum Beispiel ACTION_DOWNLOAD_FINISHED) registrieren. Dieser Empfänger wird alle Arbeiten onJobFinished() Methode delegieren:

public static final String ACTION_DOWLOAD_FINISHED = "actionDownloadFinished"; 

private BroadcastReceiver downloadFinishedReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     context.unregisterReceiver(this); //Unregister receiver to avoid receiver leaks exception 
     onJobFinished(); 
    } 
}; 

public void onStartJob() { 
    IntentFilter filter = new IntentFilter(ACTION_DOWNLOAD_FINISHED);   
    //Use LocalBroadcastManager to catch the intents only from your app 
    LocalBroadcastManager.getInstance(this).registerReceiver(downloadFinishedReceiver , filter); 

    //other job starting stuff... 
} 

Dann, nachdem die Absicht Dienst beendet hat es Arbeit ist, können Sie senden Absicht mit ACTION_DOWNLOAD_FINISHED Aktion von ihm senden:

// ...downloading stuff 
Intent downloadFinishedIntent = new Intent(Jobservice.ACTION_DOWNLOAD_FINISHED); 
//Use LocalBroadcastManager to broadcast intent only within your app 
LocalBroadcastManager.getInstance(this).sendBroadcast(intent); 

Wenn der Auftrag von der Intent-Dienst ist beendet, sendet er den Sendeauftrag, der von dem im Jobservice registrierten Empfänger abgefangen wird. Receiver ruft dann die onJobFinished() -Methode auf.

können Sie die Details dort finden: https://developer.android.com/training/run-background-service/report-status.html

+1

1. "context.unregisterReceiver (this);" verursacht "java.lang.IllegalArgumentException: Empfänger nicht registriert" -Fehler. Sie sollten die Registrierung auf die gleiche Weise aufheben, wie Sie sie registriert haben (als LocalBroadcastManager): LocalBroadcastManager.getInstance (context) .unregisterReceiver (this); –

+1

2. Der interessante Teil über die Beendigung des Jobs. JobParameters können nicht in die Absicht versetzt werden, sie mit einer Broadcast-Nachricht zu senden. Wenn Sie die Arbeit an einem Hintergrund-Thread ausführen, sollten Sie die jobFinished() -Methode aufrufen, wenn Sie fertig sind. Und muss das richtige Argument mit JobParameters verwenden. Sie erhalten es in der onStartJob() -Methode als Argument, also sollten Sie es als ein Member-Feld mJobParam speichern, damit Sie es in Ihrer onReceive() -Methode verwenden können, um jobFinished ordnungsgemäß aufzurufen. Wie folgt: if (mJobParams! = Null) jobFinished (mJobParams, false); –

-1

ich die gleiche Sache tue (Jobservice, der eine IntentService beginnt) und hier ist das, was ich getan habe:

Die kurze Geschichte ist, dass ich einen Handler verwendet mit ein Handler.Callback, das ich als Messenger an meinen IntentService weitergeben könnte, damit der IntentService eine Nachricht an Handler.Callback senden kann, um den Job zu beenden. Der Handler.Callback hat Einblick in meinen JobService, so dass er finishJob (...) aufrufen kann.

public class MyJobService extends JobService implements Handler.Callback { 

    private Handler mHandler = new Handler(this); 

    public static final String BNDL_MESSENGER = "messenger"; 
    public static final String BNDL_PARAMS = "params"; 

    public static final int FINISH_JOB_MESSAGE  = 100; 
    public static final int NEEDS_RESCHEDULE_TRUE = 0; 
    public static final int NEEDS_RESCHEDULE_FALSE = 1; 

    public boolean handleMessage(Message msg) { 
    int msgType = msg.what; 

    if (msgType == FINISH_JOB_MESSAGE) { 
     int   jobId   = msg.arg1; 
     JobParameters params   = (JobParameters)msg.obj; 
     boolean  needsReschedule = (msg.arg2 == NEEDS_RESCHEDULE_TRUE); 

     Log.i(TAG, "Finishing Job ID: " + jobId); 
     jobFinished(params, needsReschedule); 
    } else { 
     Log.e(TAG, "Message type not supported: " + msgType); 
    }  
    } 

    @Override 
    public boolean onStartJob(JobParameters params) { 

    Intent intent = new Intent(this, MyIntentService.class); 
    intent.putExtra(BNDL_MESSENGER, new Messenger(mHandler)); 
    intent.putExtra(BNDL_PARAMS, params); 

    startService(intent);      
    } 
} 

Dann sendet Ihre IntentService eine Nachricht zurück:

public class MyIntentService extends IntentService { 
    @Override 
    public void onHandleIntent(Intent intent) { 
    Messenger messenger = (Messenger)intent.getParcelableExtra(MyJobService.BNDL_MESSENGER); 
    JobParameters params = (JobParameters)intent.getParcelableExtra(MyJobService.BNDL_PARAMS); 

    if (messenger != null) { 
     Message msg = Message.obtain(); 
     msg.what = MyJobService.FINISH_JOB_MESSAGE; 
     msg.arg1 = params.getJobId(); 
     msg.arg2 = MyJobService.NEEDS_RESCHEDULE_TRUE; 
     msg.obj = params; 

     try { 
     messenger.send(msg); 
     } catch (RemoteException re) { 
     Log.e(TAG, "Couldn't send message to finish job!", re); 
     } 
    } 
    } 
} 
+0

'intent.putExtra (BNDL_PARAMS, params);' 'JobParameters' kann nicht in einer Absicht übergeben werden –