2011-10-11 14 views
5

Voglio passare una stringa e una bitmap a un servizio utilizzando AIDL. Il servizio implementa questo metodo AIDL:Inserire una bitmap in un pacchetto

void addButton(in Bundle data); 

Nel mio caso, il pacchetto contiene una stringa e una bitmap.

L'applicazione chiamante (client) ha questo codice:

... 
// Add text to the bundle 
Bundle data = new Bundle(); 
String text = "Some text"; 
data.putString("BundleText", text); 

// Add bitmap to the bundle 
Bitmap icon = BitmapFactory.decodeResource(getResources(), R.drawable.myIcon); 
data.putParcelable("BundleIcon", icon); 

try { 
    myService.addButton(data); 

} catch (RemoteException e) { 
    Log.e(TAG, "Exception: ", e); 
    e.printStackTrace(); 
} 
... 

Sul lato di servizio, ho una classe ButtonComponent con questo codice:

public final class ButtonComponent implements Parcelable { 
    private final Bundle mData; 

    private ComponComponent(Parcel source) { 
     mData = source.readBundle(); 
    } 

    public String getText() { 
     return mData.getString("BundleText"); 
    } 

    public Bitmap getIcon() { 
     Bitmap icon = (Bitmap) mData.getParcelable("BundleIcon"); 
     return icon; 
    } 

    public void writeToParcel(Parcel aOutParcel, int aFlags) { 
     aOutParcel.writeBundle(mData); 
    } 

    public int describeContents() { 
     return 0; 
    } 
} 

Dopo aver creato un ButtonComponent, il servizio crea un pulsante che utilizza il testo e l'icona dall'oggetto ButtonComponent:

... 
mInflater.inflate(R.layout.my_button, aParent, true); 
Button button = (Button) aParent.getChildAt(aParent.getChildCount() - 1); 

// Set caption and icon 
String caption = buttonComponent.getText(); 
if (caption != null) { 
    button.setText(caption); 
} 

Bitmap icon = buttonComponent.getIcon(); 
if (icon != null) { 
    BitmapDrawable iconDrawable = new BitmapDrawable(icon); 
    button.setCompoundDrawablesWithIntrinsicBounds(iconDrawable, null, null, null); 
} 
... 

Come un risultato, il pulsante viene visualizzato con il testo corretto e posso vedere lo spazio per l'icona, ma la bitmap effettiva non viene disegnata (ad es. c'è uno spazio vuoto sul lato sinistro del testo).

È corretto inserire una bitmap in un pacchetto in questo modo?

Se dovessi usare un pacchetto (rispetto a un pacchetto) esiste un modo per mantenere un singolo argomento "dati" nel metodo AIDL per mantenere insieme testo e icona?

Domanda laterale: Come si decide di utilizzare Bundles vs Parcels?

Molte grazie.

risposta

2

Risolto.

Il problema era che il PNG che stavo usando non è supportato da Android. Il codice:

icon.getConfig() 

restituisce null.

3

Ecco la risposta alla tua seconda domanda.

Fonte: http://www.anddev.org/general-f3/bundle-vs-parcel-vs-message-t517.html

A Bundle è funzionalmente equivalente a uno standard Map. Il motivo per cui abbiamo non è stato solo utilizzare una mappa perché nei contesti in cui viene utilizzato il pacchetto, le sole cose che sono legali da inserire sono primitive come stringhe, interi e così via. Poiché l'API della mappa standard consente di inserire oggetti arbitrari , ciò consentirebbe agli sviluppatori di inserire i dati nella mappa che il sistema non è in grado di supportare, il che porterebbe a strani errori di applicazione non intuitivi. Bundle è stato creato per sostituire la Map con un contenitore typesafe che rende esplicitamente chiaro che solo supporta le primitive.

Un pacco è simile a un pacchetto, ma è più sofisticato e può supportare serializzazione più complessa delle classi. Le applicazioni possono implementare l'interfaccia Parcelable per definire le classi specifiche dell'applicazione che possono essere passate, in particolare quando si utilizzano i servizi. I prodotti Parcelables possono essere più sofisticati rispetto ai pacchetti, ma questo è disponibile a un costo di overhead significativamente superiore.

Bundle e Parcel sono entrambi meccanismi di serializzazione dei dati e per la parte vengono entrambi utilizzati quando il codice dell'applicazione passa i dati tra i processi . Tuttavia, poiché il pacco è molto più elevato, il pacchetto viene utilizzato nei luoghi più comuni come il metodo onCreate , in cui l'overhead deve essere il più basso possibile.I pacchetti sono la maggior parte dei comunemente usati per consentire alle applicazioni di definire servizi con le API logiche che possono utilizzare le classi significative dell'applicazione come argomenti del metodo e restituire valori. Se avessimo richiesto Bundle, risulterebbero in API veramente grezze . In generale, dovresti mantenere le tue API di servizio il più semplice possibile, poiché le primitive serializzeranno più in modo efficiente rispetto alle classi Parcelable personalizzate.

1

Mentre gt_ebuddy dà una bella risposta, ho solo un po 'nota a margine alla tua domanda:

Problema: Si sta cercando di passare un oggetto Bitmap alla memoria, può andare bene; tuttavia, non è assolutamente opportuno passare molti oggetti Bitmap come questo. Pratica veramente cattiva

La mia soluzione: L'immagine è già esistente in resources, ha un numero unico ID; fare uso di esso. Invece di provare a passare un sacco di pesanti Bitmaps, è possibile passare il suo ID utilizzando Bundle o Parcel, ma è preferibile Bundle per una struttura dati semplice.

+0

Grazie. Nel mio scenario le bitmap sono ~ 900 byte, che è probabilmente una dimensione giusta, e voglio evitare di includerle tutte nell'APK del servizio (potrebbero esserci molti client diversi). Se ho usato un ID univoco, suppongo che entrambi i pacchetti dei clienti e del servizio conterranno il PNG reale ... giusto? – rippeltippel

+0

tutte le immagini devono essere contenute nella directory '/ res/drawable' –

Problemi correlati