2011-10-11 27 views
5

我想使用AIDL將一個字符串和一個位圖傳遞給一個服務。該服務實現此AIDL方法:將一個位圖放入一個包中

void addButton(in Bundle data); 

在我的情況下,該Bundle包含一個字符串和一個位圖。

調用應用程序(客戶端)有這樣的代碼:

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

在服務結束時,我有一個ButtonComponent類與此代碼:

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

創建ButtonComponent後,服務創建使用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); 
} 
... 

As結果是,按鈕顯示正確的文本,我可以看到該圖標的空間,但實際的位圖沒有繪製(即,文本左側有一個空白空間)。

以這種方式將一個位圖放入一個包中是否正確?

如果我應該使用Parcel(vs a Bundle),有沒有辦法在AIDL方法中保留單個'data'參數來保持文本和圖標在一起?

旁邊的問題:我如何決定使用Bundles vs Parcels?

非常感謝。

回答

2

已解決。

問題是我使用的PNG不受Android支持。 該代碼:

icon.getConfig() 

返回null。

3

這是你的第二個問題的答案。

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

包是功能上等同於標準地圖。我們 不只是使用Map的原因是因爲在使用Bundle的上下文中,合法的唯一的東西是基元,比如 Strings,int等等。由於標準Map API允許您插入任意對象,因此開發人員可以將數據放入系統實際無法支持的地圖中,這將導致出現怪異的應用程序錯誤,以及造成非直觀的應用程序錯誤。創建Bundle是爲了將Map 替換爲一個類型安全的容器,它明確表明它只支持基本類型 。

一個包類似於一個包,但更復雜,並且可以支持更復雜的類的序列化。應用程序可以使用Parcelable接口來定義應用程序特定的 類,這些類可以傳遞,尤其是在使用服務時。 附件可能比捆綁套件更復雜,但這是 的一個明顯更高的開銷成本。

Bundle和Parcel都是數據序列化機制,對於 大部分都是在應用程序代碼通過 進程傳遞數據時使用的。但是,因爲包裹的開銷要高得多,所以在更常見的地方使用捆綁包,如onCreate 方法,其中開銷必須儘可能低。包裹大多數爲 ,通常用於允許應用程序使用邏輯 定義服務,這些API可以使用應用程序有意義的類作爲方法參數 和返回值。如果我們要求Bundle,那麼會導致 真的很笨重的API。您應該總體上仍然保持服務API 儘可能簡單,因爲基元會比自定義Parcelable類有效地序列化更多 。

1

雖然gt_ebuddy給出了一個很好的答案,我只是有一個小側面說明你的問題:

問題:您正在試圖通過一個Bitmap對象的內存,它可以罰款;然而,通過許多Bitmap這樣的對象是絕對不好的。真的很糟糕的做法。

我的解決方案:該圖像已經存在於resources,它有一個獨特的ID;充分利用它。您可以使用BundleParcel來傳遞它的ID,而不是試圖通過很多重的Bitmaps,但Bundle對於簡單的數據結構更可取。

+0

謝謝。在我的場景中,位圖大約是900字節,這可能是相當大的,我想避免將它們全部包含在服務的APK中(可能有很多不同的客戶端)。如果我使用了唯一的ID,我猜客戶和服務的包都會包含實際的PNG ...對嗎? – rippeltippel

+0

所有的圖像應該包含在'/ res/drawable'目錄中 –

相關問題