Differenze tra Intent e PendingIntent


97

Ho letto alcuni articoli ed entrambi sembrano fare la stessa cosa e mi chiedevo qual è la differenza tra l'avvio del servizio in questo modo:

Intent intent = new Intent(this, HelloService.class);
startService(intent);

o così:

Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this, MyService.class);
PendingIntent pintent = PendingIntent.getService(this, 0, intent, 0);
AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 30*1000, pintent); 

Mentre leggo, questi due fanno la stessa cosa, se nel servizio restituisci un parametro START_STICKY;


Non c'è alcuna differenza. Cosa ti fa pensare che ci sarebbe stato? Nel primo caso lo stai avviando "adesso" e nel secondo lo stai solo programmando per un orario / dati successivo.
Squonk

Risposte:


150

Intento

Un intento Android è un oggetto che trasporta un intento, cioè un messaggio da un componente a un altro componente all'interno o all'esterno dell'applicazione. Gli intent possono comunicare messaggi tra uno qualsiasi dei tre componenti principali di un'applicazione: attività, servizi e BroadcastReceivers.

L'intento stesso, un oggetto Intent, è una struttura dati passiva. Contiene una descrizione astratta di un'operazione da eseguire.

Ad esempio: supponi di avere un'attività che deve avviare un client di posta elettronica e inviare un'e-mail. Per fare ciò, la tua attività invierà un Intent con l'azione ACTION_SEND, insieme al selettore appropriato, al Resolver Intent Android:

Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this

Il selettore specificato fornisce l'interfaccia appropriata per l'utente per scegliere come inviare i dati di posta elettronica.

INTENTI ESPLICITI

// Explicit Intent by specifying its class name
   Intent i = new Intent(this, TargetActivity.class);
   i.putExtra("Key1", "ABC");
   i.putExtra("Key2", "123");

// Starts TargetActivity
   startActivity(i);

INTENTI IMPLICITI

// Implicit Intent by specifying a URI
   Intent i = new Intent(Intent.ACTION_VIEW, 
   Uri.parse("http://www.example.com"));

// Starts Implicit Activity
   startActivity(i); 

In attesa di intento

Un PendingIntent è un token che fornisci a un'applicazione esterna (ad esempio NotificationManager, AlarmManager, AppWidgetManager della schermata iniziale o altre applicazioni di terze parti), che consente all'applicazione esterna di utilizzare le autorizzazioni dell'applicazione per eseguire una porzione di codice predefinita.

Assegnando un PendingIntent a un'altra applicazione, le concedi il diritto di eseguire l'operazione che hai specificato come se l'altra applicazione fosse te stesso (con le stesse autorizzazioni e identità). Pertanto, dovresti stare attento a come costruisci PendingIntent: quasi sempre, ad esempio, l'intento di base che fornisci dovrebbe avere il nome del componente impostato esplicitamente su uno dei tuoi componenti, per assicurarti che venga inviato alla fine lì e da nessun'altra parte.

Esempio di intento in sospeso: http://android-pending-intent.blogspot.in/

Fonte: Android Intents e Android Pending Intents

Spero che questo ti aiuti.


26

PendingIntentè un involucro di Intent. L'app straniera che riceve il PendingIntent, non conosce il contenuto di Intentcui è incluso PendingIntent. La missione dell'app straniera è quella di rispedire l'intento al proprietario quando vengono soddisfatte alcune condizioni (ad esempio: allarme con pianificazione o notifica con clic ...). Le condizioni sono fornite dal proprietario ma elaborate da app straniera (ad esempio: allarme, notifica).

Se un'app straniera ha inviato l'intento alla tua app, significa che l'app straniera conosce il contenuto dell'intento. e l'app esterna prende la decisione di inviare l'intento, quindi l'app deve elaborare l'intento per soddisfare alcune condizioni => l'app ottiene la risorsa delle prestazioni del sistema.


5

Un'altra semplice differenza:

  • L'intento normale morirà non appena l'app viene interrotta.

  • Gli intenti in sospeso non muoiono mai. Saranno vivi finché sarà necessario al servizio di allarme, al servizio di localizzazione o ad altri servizi.


1

Avvio dei servizi regolarmente tramite AlarmManager

Come per le attività, il sistema Android può interrompere il processo di un servizio in qualsiasi momento per risparmiare risorse. Per questo motivo non puoi semplicemente utilizzare un TimerTasknel servizio per assicurarti che venga eseguito regolarmente.

Quindi, per una corretta programmazione del Servizio utilizzare la AlarmManagerclasse.

AGGIORNARE:

Quindi non vi è alcuna differenza effettiva tra i due. Ma a seconda che tu voglia assicurare o meno l'esecuzione del servizio, puoi decidere cosa usare in quanto per il primo non c'è garanzia e per il dopo lo è.

Maggiori informazioni su AndroidServices .


2
Questo in realtà non risponde alla domanda dell'OP che è "qual è la differenza" tra l'avvio diretto di un servizio e l'avvio di un servizio con un allarme. Anche l'OP ha probabilmente visto l'articolo a cui ti colleghi poiché il codice nell'articolo è quasi identico a quello che l'OP ha pubblicato.
Squonk

Vuoi dire che l'avvio di un servizio da AlarmManager è più sicuro e ha meno probabilità di essere interrotto rispetto a un'attività? Penso che sia sbagliato. Puoi spiegare per favore. @VedPrakash. Inoltre, penso che il contesto che si passa durante la creazione di un intento per avviare il servizio sia più importante. L'utilizzo del contesto dell'applicazione (getApplicationContext ()) anziché quello di un'attività (this) dovrebbe essere più sicuro.
Parth Kapoor

@ Eu.Dr. Ti consiglio di utilizzare il gestore degli allarmi che verrà attivato ogni volta che X ... esegui l'attività .. Perché? perché se usi i servizi potrebbe essere chiuso ad un certo punto e potresti finire per saltare alcuni aggiornamenti in un certo momento (sconosciuto). Per dubbi sul contesto, non usarlo mai getApplicationContext()o usarlo quando lo vuoi strettamente, leggi semplicemente - quando-chiamare-contesto-attività-o-contesto-applicazione ( stackoverflow.com/questions/7298731/… ).
Mio Dio,

1

Funzionalmente, non c'è differenza.

Il significato di PendingIntent è che puoi gestirlo con un'altra applicazione che in seguito potrà usarlo come se l'altra applicazione fosse te stesso. Ecco la spiegazione pertinente dalla documentazione :

Assegnando un PendingIntent a un'altra applicazione, le concedi il diritto di eseguire l'operazione che hai specificato come se l'altra applicazione fosse te stesso (con le stesse autorizzazioni e identità). Pertanto, dovresti stare attento a come costruisci PendingIntent: quasi sempre, ad esempio, l'intento di base che fornisci dovrebbe avere il nome del componente impostato esplicitamente su uno dei tuoi componenti, per assicurarti che venga inviato alla fine lì e da nessun'altra parte.

Un PendingIntent stesso è semplicemente un riferimento a un token gestito dal sistema che descrive i dati originali utilizzati per recuperarlo.

Quindi PendingIntent è solo un riferimento ai dati che rappresentano l'Intent originale (quello utilizzato per creare il PendingIntent).


4
Dire che dal punto di vista funzionale non c'è differenza non è corretto. Se le funzioni di entrambi sono uguali, perché avere due al primo posto? La differenza più importante è che PendingIntent viene eseguito dal componente remoto (Like NotificationManager) con le stesse autorizzazioni del componente che lo consegna (quello che crea la notifica).
Aniket Thakur
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.