2016-03-01 21 views
8

Ho una situazione in cui mi sento come se stessi per reinventare la ruota o andare in giro per le case, per gestire qualcosa per cui esiste già un "progetto" - quindi prima di farlo, speravo Potrei avere una seconda opinione per favore.Gestire le chiamate di servizio remote

Ho un servizio remoto. È un servizio permanente in primo piano a causa della natura/funzionalità insolite dell'applicazione stessa.

Sto scrivendo una libreria in modo che le applicazioni di terzi possano collegarsi al servizio e utilizzare le API che espongo. Poiché sto gestendo personalmente il threading e la maggior parte dei callback sarà di natura asincrona, sto utilizzando un approccio AIDL, con classi personalizzate che sono "Parceled up" per fornire i parametri necessari al Servizio. Tutto finora, funziona perfettamente.

Il costrutto del mio codice di servizio è molto simile allo RemoteService API example, quindi mi riferirò a questo, poiché la pubblicazione del mio codice specifico non modifica la domanda.

Come with the example, l'interfaccia di ogni richiesta viene salvata in un RemoteCallbackList, che sembra essere una soluzione pratica per alcuni altri fondamenti.

Tuttavia, il mio servizio non fornisce le stesse informazioni a un gruppo di 'ricevitori in attesa' come l'uso del seguente frammento dimostra:

int i = callbacks.beginBroadcast(); 
while (i > 0) { 
    i--; 
    try { 
     callbacks.getBroadcastItem(i).somethingHappened(); 
    } catch (RemoteException e) { 
     // The RemoteCallbackList will take care of removing 
     // the dead object for us. 
    } 
} 
callbacks.finishBroadcast(); 

Invece, le richieste sono di molti tipi diversi e quindi mi è necessario tenere traccia di quale esatto oggetto di interfaccia sono per inviare i risultati a. Ogni singola richiesta può implicare ulteriori richieste e/o elaborazioni web asincrone e dover restituire l'oggetto callback a ciascuno di questi (tramite un costruttore o solo un parametro del metodo) è dove sento che sto per fare qualcosa di molto noioso e prolisso per risolvere un problema che posso forse raggiungere in modo semplicistico in un altro modo?

L'attività sarebbe facilitata se potessi garantire che la prima richiesta in, sarebbe il primo risultato e quindi utilizzare semplicemente l'ordine in RemoteCallbackList prima di rimuovere il riferimento a loro, ma questo non è il caso, a causa di i diversi tempi di elaborazione dei diversi tipi di richieste.

Modifica - Sembra che il RemoteCallbackList è supportato da un ArrayMap e quindi non credono ordinato comunque?

Non riesco a trovare alcun modo documentato di restringere il punto in cui è stata originata la richiamata nella RemoteCallbackList, anche se, se potessi, avrei comunque bisogno di un qualche tipo di identificatore persistente per sapere cosa stavo cercando .... Stumped .

Grazie per aver letto fino a qui, qualsiasi idea è la benvenuta.

Modifica - A scopo di pseudo esempio. Immagina che le richieste API riguardino i libri.

// requests 
bookExists(String title) 
bookContent(String title) 

// response 
bookExists(boolean exists) 
bookContent(ArrayList<String> words, int pageTotal) 

Come si può vedere da quanto sopra, a parità di condizioni, una richiesta remota per un libro più piccolo o l'esistenza di un libro, può completare ed essere pronti a rispondere prima di una richiesta di un libro più lungo, anche se è stato richiesto dopo. È qui che devo seguire il "requester" ed è il design che sto cercando.

+0

È possibile chiarire se si desidera inviare la richiamata al sottoinsieme di destinatari o si intendeva inviare dati diversi a ciascuno dei destinatari? – RocketRandom

+0

@RocketRandom Sarebbero dati univoci per ogni – brandall

+0

È possibile mantenere una HashMap di dove CustomMsgReceiverInfo è una struttura di dati che è possibile utilizzare per distinguere i dati da inviare. Il chiamante passerà questo nella chiamata registerCallback. – RocketRandom

risposta

2

Se ho capito bene, tutto ciò che devi fare è rispondere alle tue richieste da RemoteCallbackList usando la stessa interfaccia, ma con diverse strutture di dati di risposta.

Immagino che il modo più semplice sia quello di fare in modo che le richieste forniscano informazioni sul tipo di struttura dei dati di ritorno che desiderano. Il modo più ovvio (forse anche stupido) è quello di inviarti il ​​nome della classe che devi istanziare e compilare. In modo più sofisticato puoi semplicemente creare una lista che il nome dell'elemento dovrebbe essere portato su richiesta e che definirà il corretto classe della struttura dei dati da istanziare e restituire.

Il secondo modo è quello di avere una sorta di resolver di risposta - una logica che rileverà il tipo di dati che la richiesta potrebbe desiderare. Ma IMHO sembra troppo ambiguo, piuttosto complicato e non molto comodo da supportare.

In ogni caso - è abbastanza dubbio che troverete una soluzione universale per un caso del genere, perché non è comune.

Spero che questo aiuti.

+0

Grazie per la risposta. Le richieste inviano il tipo di risposta che si aspettano, determinato dall'API (metodo) chiamato tramite AIDL. Richieste multiple dello stesso tipo di risposta possono essere eseguite simultaneamente, il che lascia comunque la domanda originale di quale risposta preparata deve essere inviata a quale callback/binder. – brandall

+0

Immagino che sia solo una questione di cache. Voglio dire, potresti semplicemente mantenere le tue risposte preparate un po 'di tempo nella speranza che alcune nuove richieste possano ottenerlo. – domax

+0

Ho aggiunto una modifica alla mia domanda: la cache non è rilevante qui, poiché i dati di risposta sono diversi. – brandall

Problemi correlati