Ich habe den folgenden Text auf der Android Developers Site gelesen, und zwar unter Rahmenthemen -> Dienste -> Starten eines Dienstes .
Dort heißt es:
Wenn der Dienst keine Bindung bereitstellt, ist die mit startService () bereitgestellte Absicht der einzige Kommunikationsmodus zwischen der Anwendungskomponente und dem Dienst. Wenn der Dienst jedoch ein Ergebnis zurücksenden soll, kann der Client, der den Dienst startet, ein PendingIntent für eine Übertragung (mit getBroadcast ()) erstellen und es an den Dienst in dem Intent übermitteln, mit dem der Dienst gestartet wird. Der Dienst kann dann die Sendung verwenden, um ein Ergebnis zu liefern.
Ich habe dazu ein paar Fragen:
Service
s undIntentService
s?Service
erreicht werden? Der Dienst kann dann die Sendung verwenden, um ein Ergebnis zu liefern. und auch wo würde die erwähnte Sendung das Ergebnis an den ursprünglichen Kunden/die ursprüngliche Aktivität liefern? Gibt es eine Methode, die überschrieben werden sollte (wie onActivityResult()
) oder so?
Die Frage wurde vor einigen Monaten gestellt, aber falls noch jemand nach einer Antwort sucht, hoffe ich, dass ich helfen kann.
Im folgenden Beispiel haben wir einen lokalen Service, der für einige zeitraubende Vorgänge verantwortlich ist. Activity stellt die Anforderungen an den Dienst, bindet sie jedoch nicht daran, sondern sendet die Absicht mit der Anforderung. Darüber hinaus enthält Activity die Informationen von BroadcastReceiver, die zurückgerufen werden sollten, wenn der Dienst mit der angeforderten Aufgabe abgeschlossen ist. Die Informationen werden von PendingIntent übergeben. Der Dienst verarbeitet die Aufgabe im Hintergrundthread. Wenn die Aufgabe abgeschlossen ist, sendet der Dienst den BroadcastReceiver mit einer Antwort.
1. BroadcastReceiver-Unterklasse erstellen:
public class DataBroadcastReceiver extends BroadcastReceiver {
static Logger log = LoggerFactory.getLogger(DataRequestService.class);
@Override
public void onReceive(Context context, Intent intent) {
log.info(" onReceive");
}
}
Dieser Rundfunkempfänger wird vom Dienst benachrichtigt, wenn die Aufgabe erledigt ist.
2. Service erstellen
public class DataRequestService extends Service {
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
log.info("handleMessage");
//... performing some time-consuming operation
Bundle bundle = msg.getData();
PendingIntent receiver = bundle.getParcelable("receiver");
// Perform the operation associated with PendingIntent
try {
//you can attach data from the operation in the intent.
Intent intent = new Intent();
Bundle b = new Bundle();
//b.putString("key", value);
intent.putExtras(b);
receiver.send(getApplicationContext(), status, intent);
} catch (CanceledException e) {
e.printStackTrace();
}
}
}
@Override
public void onStart(Intent intent, int startId) {
Bundle bundle = intent.getExtras();
msg.setData(bundle);
mServiceHandler.sendMessage(msg);
}
Der wichtigste Teil ist die handleMessage () -Methode. Der Dienst führt einfach den Broadcast-Vorgang aus, um die Ergebnisse an den Broadcast Receiver zu liefern.
3. Sie müssen Ihren Rundfunkempfänger und -dienst auch in Manifest.xml registrieren.
<manifest xmlns:Android="http://schemas.Android.com/apk/res/Android"
package="com.ramps.servicetest"
Android:versionCode="1"
Android:versionName="1.0" >
....
<service Android:name=".service.DataRequestService" Android:exported="false"/>
<receiver Android:name=".service.DataBroadcastReceiver"></receiver>
</application>
</manifest><br>
4. Und schließlich beantrage deine Aktivität bei Activity:
Intent serviceIntent = new Intent(context, DataRequestService.class);
@Override
public void onClick(View v) {
//this is the intent that will be broadcasted by service.
Intent broadcastReceiverIntent = new Intent(context, DataBroadcastReceiver.class);
//create pending intent for broadcasting the DataBroadcastReceiver
PendingIntent pi = PendingIntent.getBroadcast(context, 0, broadcastReceiverIntent, 0);
Bundle bundle = new Bundle();
bundle.putParcelable("receiver", pi);
//we want to start our service (for handling our time-consuming operation)
Intent serviceIntent = new Intent(context, DataRequestService.class);
serviceIntent.putExtras(bundle);
context.startService(serviceIntent);
}
5. Antwort auf den ursprünglichen Kunden/die ursprüngliche Aktivität liefern .
Sie können abstrakte Aktivitäten haben, von denen sich alle Ihre Aktivitäten erstrecken. Diese kurze Aktivität kann sich automatisch als Antwort-Listener im Rundfunkempfänger registrieren/abmelden. Hier gibt es nicht viele Optionen, aber es ist wichtig, dass Sie, wenn Sie statische Verweise auf Ihre Aktivität beibehalten, das Removal löschen, wenn die Aktivität zerstört wird.
Grüße,
Rampen
Um eine Kommunikation zwischen service und activity durchzuführen. Sie können Binder auch wie in Offizielles Android-Beispiel http://developer.Android.com/reference/Android/app/Service.html#LocalServiceSample erwähnt verwenden.
Detaillierte Informationen finden Sie in diesen Antworten https://stackoverflow.com/a/36983011/4754141
Wie geschrieben hier
Die Kommunikation zwischen Dienst und Aktivität kann mithilfe von PendingIntent erfolgen. Damit wir createPendingResult () . CreatePendingResult () verwenden können, wird ein neues PendingIntent-Objekt erstellt, das Sie dem Service übergeben können zu verwenden und Ergebnisdaten an Ihre Aktivität in onActivityResult (int, int, Intent) zurückzuschicken. Da ein PendingIntent Parcelable ist und daher in ein Wenn Sie zusätzlich beabsichtigen, kann Ihre Aktivität diese PendingIntent an den Service übergeben. Der Service kann wiederum die Methode send () Für PendingIntent aufrufen, um die Aktivität über OnActivityResult von zu benachrichtigen ein Event.
Aktivität
public class PendingIntentActivity extends AppCompatActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); PendingIntent pendingResult = createPendingResult( 100, new Intent(), 0); Intent intent = new Intent(getApplicationContext(), PendingIntentService.class); intent.putExtra("pendingIntent", pendingResult); startService(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == 100 && resultCode==200) { Toast.makeText(this,data.getStringExtra("name"),Toast.LENGTH_LONG).show(); } super.onActivityResult(requestCode, resultCode, data); } }
Bedienung
public class PendingIntentService extends Service { private static final String[] items= { "lorem", "ipsum", "dolor", "sit", "amet", "consectetuer", "adipiscing", "elit", "morbi", "vel", "ligula", "vitae", "arcu", "aliquet", "mollis", "etiam", "vel", "erat", "placerat", "ante", "porttitor", "sodales", "pellentesque", "augue", "purus" }; private PendingIntent data; @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { data = intent.getParcelableExtra("pendingIntent"); new LoadWordsThread().start(); return START_NOT_STICKY; } @Override public IBinder onBind(Intent intent) { return null; } @Override public void onDestroy() { super.onDestroy(); } class LoadWordsThread extends Thread { @Override public void run() { for (String item : items) { if (!isInterrupted()) { Intent result = new Intent(); result.putExtra("name", item); try { data.send(PendingIntentService.this,200,result); } catch (PendingIntent.CanceledException e) { e.printStackTrace(); } SystemClock.sleep(400); } } } } }