5

Sto cercando di capire come comunicare tra le applicazioni in Android, non solo tra le istanze Activity.Sta usando Parcelable il modo giusto per inviare dati tra le applicazioni?

Ho impostato un "client" che invia un oggetto Messenger a un servizio (nello Intent inviato al servizio); il servizio crea un obj Message e lo invia di nuovo al "client" utilizzando messenger.send(message). Funziona bene finché non provo a usare Message.obj per tenere un oggetto.

Ho creato il mio codice Parcelable classe MyParcelable nel servizio e lo inserisco nel messaggio. Tutto funziona finché il messaggio non è riarmato nel 'client'. L'unmarshall fallisce perché il 'client' non ha accesso alla classe MyParcelable. È ovvio: sono in pacchetti diversi (ad esempio com.whatever.myclient e com.whatever.myserver). Questo è completamente il modo sbagliato di fare questo?

Ho anche provato a creare un Parcel e inviarlo (entrambe le applicazioni avrebbero quindi accesso alla classe) - ma Parcel non è Parcelable. Ho letto che i programmi di caricamento classi sono in uso ma non capisco come distaccare i caricatori di classe in applicazioni separate (processi, se capisco l'architettura di Android a tale riguardo). Cioè, come si può 'insegnare' un caricatore di classi su una classe che esiste nell'altro caricatore di classi? Sembra certamente che dovrebbe esserci un ovvio 'questo è come lo fai' ma non l'ho ancora visto.

risposta

2

Non è possibile annullare l'unmarshall di una classe in un processo che non ha alcuna conoscenza di questa classe (come già sottolineato correttamente). Se si desidera MyParcelable da inviare al vostro Service, allora avete bisogno di includere MyParcelable nel Service a costruire, e includono il diritto ClassLoader da utilizzare quando unmarshalling, perché unmarshalling è fatto da un thread di sistema, che non conosce cosa MyParcelable è anche se lo hai incluso in fase di compilazione.

EDIT:

(a) includere MyParcelable in 2 pkgs diversi e li hanno essere visti come la stessa classe

Fare una libreria di classi comuni e includerlo nel entrambe le applicazioni (l'applicazione e Service). Puoi contrassegnarlo come libreria Android (in Eclipse è proprio sotto le proprietà Android del progetto) o esportarlo come JAR e importarlo in entrambe le app. È sempre una buona idea avere classi indipendenti in una libreria invece di inserirle direttamente nelle app. In questo modo è possibile riutilizzare in altri progetti;)

(2) includono il ClassLoader destra (dove posso avere il diritto di classe loader, per esempio)

È possibile ottenere il ClassLoader dal thread corrente durante l'esecuzione del codice. Ovviamente questo ClassLoader conosce le tue classi perché sta eseguendo il tuo codice;) Ad esempio in Activity#onCreate(), puoi fare Thread.currentThread.getContextClassLoader(). Poiché la classe MyParcelable è inclusa anche nello Service, è possibile fare lo stesso per ottenere un valore unmarshall valido da ClassLoader.

Un'altra soluzione per IPC è quello di definire un AIDL interface quindi non c'è bisogno di implementare Parcelable.

+2

Ehi m0skit0, dovresti espanderlo un po '. Stavo per rispondere, ma tu hai esattamente ragione. Un po 'più di spiegazione lo renderebbe più chiaro. I prodotti Parcelables funzionano solo se i ClassLoaders eseguono il marshalling e l'unmarshalling dei dati hanno copie identiche della classe Parcelable ... –

+0

Suoni buoni ma non ho idea di come fare entrambi (a) includere MyParcelable in 2 diversi pkgs e farli vedere come lo stesso class o (2) include il giusto ClassLoader (da dove ottengo, ad esempio, il caricatore di classe giusto). Grazie per la tua risposta, ma hai circa 2 livelli di esperienza al di sopra della mia comprensione. –

+0

Ho aggiornato la mia risposta. – m0skit0

1

Se non si desidera utilizzare un livello di persistenza da qualche parte (io utilizzo apis del cloud), è possibile eseguire un servizio in un processo separato e associare al servizio le rispettive app che necessitano dei dati dell'oggetto tipo detentore di valore condiviso. il servizio sarebbe dove costruisci e ottieni i valori obj per conto di connettere app (vincolanti).

+0

Questi sono entrambi ottimi suggerimenti e li manterrò sicuramente da vicino mentre procedo. Sono a questo punto principalmente cercando di afferrare i concetti di Parcelable e Class Loader nella speranza che li capirò abbastanza per essere in grado di usarli in modo appropriato. Grazie mille per la tua risposta. –

+0

conosce i fondamenti di Android e il ciclo di vita delle attività. questo potrebbe essere più importante dei concetti di CL. http://developer.android.com/reference/android/app/Activity.html http://developer.android.com/guide/components/fundamentals.html –

+0

imo - inter app, il più semplice sarebbe utilizzare 'intento -extra 'campi e ai guess un chooser che consentirebbe la selezione dell'app target. –

1

OK, ho trovato il "modo semplice" che stavo cercando. Puoi mettere un pacchetto nel campo Message.obj. Bundle è Parcelable quindi può essere trasportato tra client e server. Non c'è alcun problema sul fatto che il server non sappia quale classe sta ricevendo poiché il pacchetto è "integrato" in Android Java. E Bundle può apparentemente includere "sotto-Bundles" con in. Questo è più semplice di dover affrontare assicurando che entrambe le parti conoscano la definizione di una classe definita dall'utente. Grazie per le risposte sopra - ho sicuramente apprezzato le informazioni!

Problemi correlati