2011-10-11 14 views
5

Chcę przekazać ciąg i bitmapę do usługi przy użyciu AIDL. Usługa implementuje tę metodę AIDL:Umieszczanie bitmapy w pakiecie

void addButton(in Bundle data); 

W moim przypadku Pakiet zawiera ciąg i bitmapę.

aplikacji wywołującej (klient) ma ten kod:

... 
// 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(); 
} 
... 

Na koniec służby, mam klasę ButtonComponent z tym kodem:

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; 
    } 
} 

Po utworzeniu ButtonComponent, usługa tworzy przycisk wykorzystujący tekst i ikonę z obiektu 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); 
} 
... 

Jako w rezultacie przycisk jest wyświetlany z poprawnym tekstem i widzę miejsce na ikonę, ale faktyczna mapa bitowa nie jest rysowana (tj. po lewej stronie tekstu jest puste miejsce).

Czy to prawda, aby umieścić bitmapę w pakiecie w ten sposób?

Jeśli powinienem użyć paczki (w porównaniu z paczką) czy istnieje sposób na zachowanie pojedynczego argumentu "dane" w metodzie AIDL, aby zachować tekst i ikonę razem?

Pytanie boczne: Jak mogę zdecydować się na użycie pakietów zamiast paczek?

Wielkie dzięki.

Odpowiedz

2

Rozwiązany.

Problem polegał na tym, że używany PNG nie jest obsługiwany przez Androida. Kod:

icon.getConfig() 

zwraca zero.

3

Oto odpowiedź na drugie pytanie.

Źródło: http://www.anddev.org/general-f3/bundle-vs-parcel-vs-message-t517.html

Bundle jest funkcjonalnym odpowiednikiem standardowej mapie. Powodem dla którego była nie tylko mapa, ponieważ w kontekstach, w których jest używany pakiet, , jedynymi rzeczami, które można w nim umieścić są prymitywy, takie jak ciągi znaków, int i tak dalej. Ponieważ standardowy interfejs Map API pozwala wstawiać dowolne obiekty w postaci , umożliwiłoby to programistom umieszczenie danych w mapie, której system nie może w rzeczywistości obsłużyć, co prowadzi do dziwnych, nieintuicyjnych błędów aplikacji. Utworzono pakiet zastępujący Mapę pojemnikiem z zabezpieczeniami przed kopiowaniem, który wyraźnie informuje, że obsługuje tylko prymitywy tylko .

Paczka jest podobna do paczki, ale jest bardziej wyrafinowana i może wspierać bardziej złożoną serializację zajęć. Aplikacje mogą zaimplementować interfejs Parcelable w celu zdefiniowania specyficznych dla aplikacji klas , które można przekazywać, szczególnie podczas korzystania z usług. Parcelables mogą być bardziej wyrafinowane niż Pakiety, ale to jest o koszt znacznie wyższy narzut.

Pakiet i działka są mechanizmami serializacji danych, a dla części większość z nich jest używana, gdy kod aplikacji przekazuje dane w procesach . Ponieważ jednak paczka jest znacznie wyższa narzutowo niż pakiet , pakiety są używane w bardziej popularnych miejscach, takich jak metoda onCreate , gdzie obciążenie musi być tak niskie, jak to możliwe.Pakiety są najczęściej używane do zezwalania aplikacjom na definiowanie usług za pomocą logicznych interfejsów API , które mogą używać klas znaczących dla aplikacji jako argumenty metody i zwracać wartości. Gdybyśmy potrzebowali tam Pakietu, spowodowałoby to naprawdę niezgadzające się interfejsy API. Powinieneś zasadniczo zachować swoje Service APIs tak proste, jak to możliwe, ponieważ prymitywy będą serializować więcej efektywnie niż niestandardowe klasy paczek.

1

Podczas gt_ebuddy daje miłe odpowiedzi, po prostu mieć trochę dygresja na pytanie:

Problem: Próbujesz przekazać Bitmap obiektu do pamięci, to może być w porządku; jednak absolutnie nie jest dobrze przejść przez wiele takich obiektów. Naprawdę zła praktyka.

Moje rozwiązanie: Obraz już istnieje w resources, ma unikatowy ID; wykorzystaj z tego. Zamiast próbować przekazać dużo ciężkich Bitmaps, można przekazać jego ID przy użyciu Bundle lub Parcel, ale lepiej jest dla prostej struktury danych.

+0

Dziękuję. W moim scenariuszu bitmapy mają rozmiar ~ 900 bajtów, co jest prawdopodobnie dość dużym rozmiarem i chcę uniknąć umieszczania ich wszystkich w pliku APK usługi (może być wielu różnych klientów). Jeśli użyłbym unikalnego identyfikatora, to sądzę, że zarówno pakiety klientów, jak i usług będą zawierały rzeczywisty plik PNG ... prawda? – rippeltippel

+0

wszystkie twoje obrazy powinny znajdować się w katalogu '/ res/drawable' –