2016-03-21 18 views
17

Ho un servizio remoto, a cui possono collegarsi le applicazioni esterne. Ci sono situazioni in cui potrei desiderare di rifiutare l'associazione. According to the documentation,Servizio remoto nega l'autorizzazione suBind

Restituire il canale di comunicazione al servizio. Può restituire null se i client non possono collegarsi al servizio.

@Override 
public IBinder onBind(final Intent intent) { 
    return null; 
} 

Tornando nullo fa effettivamente non restituire un oggetto IBinder e impedisce quindi la connessione, tuttavia l'applicazione chiamante non riceve correttamente questa 'informazione'.

boolean bound = context.bindService(intent, serviceConnection, flagsHere); 

Se restituisce null o no dal servizio, questo restituisce sempre true?

According to the documentation,

Returns - Se si è legata con successo al servizio, vero è tornato; falso viene restituito se la connessione non viene effettuata in modo da non ricevere il servizio oggetto

ho dato per scontato che il ritorno nulla da onBind avrebbe causato bindService per restituire false. Ipotesi sono mai una buona idea ...

Tornando nulla impedisce tuttavia il ServiceConnection dall'essere istanziata invocato, ma una conseguenza di questo sarebbe alcuna possibilità di controllare se il legante è infatti nullo in onServiceConnected.

Quindi, la mia domanda - Come fa un'applicazione a "sapere" se la richiesta di associazione è stata respinta?

Inoltre, se decido al volo che una richiesta di onRebind (dopo aver restituito in precedenza vero dal onUnbind) dovrebbe essere rifiutato, mi sembra di essere in grado di ignorare il comportamento per evitare che questo:

@Override 
public void onRebind(final Intent intent) { 

    if (shouldAllowRebind(intent)) { 
     super.onRebind(intent); 
    } else { 
     // ? 
    } 
} 

Spero che qualcuno possa far luce per me. Grazie in anticipo.

+4

Il valore restituito da 'bindService()' è stato un problema per un po 'di tempo. "Come fa un'applicazione a sapere" se la richiesta di associazione è stata negata?"- presumibilmente, il suo' ServiceConnection' non viene mai chiamato con 'onServiceConnected()'. – CommonsWare

+0

Grazie a @CommonsWare speravo che avessi individuato questa domanda! Come 'bindService()' è ritornato vero, l'app è rimasta in ' limbo 'aspettando 'ServiceConnection' per chiamare' onServiceConnected() 'Come non fa (a causa di comportamenti scorretti), suggeriresti un thread del monitor che aspetta alcuni secondi e poi controlla se un identificatore' boolean' ha segnalato che il metodo era chiamato? Altrimenti, segna il contesto utilizzato come null e spera che GC lo riordini? Sono preoccupato che Android creda che l'app sia legata al Servizio e la tenga in memoria – brandall

+0

"suggeriresti un thread del monitor che aspetta alcuni secondi e poi controlla se un identificatore booleano ha segnalato che il metodo è stato chiamato? "- personalmente, vorrei cercare di risolvere il problema generale in qualche altro modo (ad esempio, rifiutando le singole chiamate API al raccoglitore) invece di cercare di rifiutare l'associazione Dato questo imple mentazione, usare qualcosa per implementare un timeout (ad esempio, 'postDelayed()' su un 'View') potrebbe essere la scelta migliore. "Altrimenti, segna il contesto utilizzato come null e spera che GC lo riordini?" - scusa, ma non ho capito questa parte. – CommonsWare

risposta

7

Probabilmente è necessario creare una soluzione alternativa. Vedo due opzioni qui:

  • Restituire un Binder senza alcuna funzionalità se la richiesta deve essere negata. Il cliente deve quindi verificare se la funzionalità desiderata è presente.
  • Restituire sempre lo stesso Binder, ma lasciare che ogni metodo lanci uno Exception (ad esempio SecurityException) se la chiamata non è consentita. (Questo è stato anche suggerito da @CommonsWare nei commenti)

Preferirei personalmente il secondo approccio in quanto è più flessibile. (ad esempio consente/nega per chiamata, risolve il problema di negare materiale dopo una riconnessione, ecc.)

+0

Grazie per la risposta - potresti fare riferimento nel codice in cui 'bindService non crea il Servizio in modo sincrono? Per favore? Per 'Sei sicuro che il tuo onServiceConnected non viene chiamato? '100% non è successo per te? Correggerò la dicitura nella mia domanda, penso che "invocato" sarebbe stata una terminologia migliore che "istanziata"? – brandall

+0

Il modo più semplice per mostrare ciò è se si guarda l'origine della chiamata onBind: proviene da un gestore. Come probabilmente sapete, gli handler sono usati principalmente per la comunicazione asincrona (interprocesso). http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.1.1_r1/android/app/ActivityThread.java#1391 – F43nd1r

+0

Il primo paragrafo della risposta è totalmente errato. Se aggiungi punti di interruzione semplici, vedrai che 'bindService' è in attesa della risposta di' onBind' e prima che questo 'onStartCommand' venga chiamato indipendentemente dal fatto che il servizio sia in esecuzione o meno. Non sono sicuro di cosa intendi nel tuo commento: che il sistema userà l'IPC per comunicare la risposta di "onBind"? – brandall

Problemi correlati