Poner un mapa de bits en un paquete
Quiero pasar una cadena y un mapa de bits a un servicio utilizando AIDL. El servicio implementa este método AIDL:
void addButton(in Bundle data);
En mi caso, el Bundle contiene una cadena y un mapa de bits.
- ¿Por qué utilizar parcelable cuando se puede realizar la misma tarea utilizando variables estáticas?
- Arraylist en objeto parcelable
- Algunos objetos parcelables reunidos en un intento / paquete podrían interferir y comprometer la lectura de Intención / Bundle?
- ¿Qué cargador de clases usar con Parcel.readHashMap?
- ¿Cómo ordenar y unmarshall un parcelable a un arsenal del byte con la ayuda del paquete?
La aplicación que llama (cliente) tiene este código:
... // 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(); } ...
En el extremo del servicio, tengo una clase ButtonComponent con este código:
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; } }
Después de crear un ButtonComponent, el servicio crea un botón utilizando el texto y el icono del objeto 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); } ...
Como resultado, el botón se muestra con el texto correcto y puedo ver el espacio para el icono, pero el mapa de bits real no está dibujado (es decir, hay un espacio vacío en el lado izquierdo del texto).
¿Es correcto colocar un mapa de bits en un paquete de esta manera?
Si debo utilizar un paquete (vs un paquete) ¿hay alguna manera de mantener un solo argumento de 'datos' en el método AIDL para mantener el texto y el icono juntos?
Pregunta secundaria: ¿Cómo decido usar Bundles vs Parcels?
Muchas gracias.
- Android Store un objeto parcelable en SQLite
- Anidado Parcelling: RuntimeException - Unmarshalling tipo desconocido código 3211319 en el desplazamiento 440
- Cómo enviar objetos a través de un paquete
- Cómo guardar ArrayList personalizado en la rotación de la pantalla de Android?
- Crea un objeto java personalizado Parcelable en Android
- Lista de objeto personalizado y Parcelable dar NullPointerException
- Paquete interior parcelable que se agrega a la parcela
- Cómo definir parcelable de tipo de interfaz en el archivo .aidl?
Aquí está la respuesta para su segunda pregunta.
Fuente: http://www.anddev.org/general-f3/bundle-vs-parcel-vs-message-t517.html
Un paquete es funcionalmente equivalente a un mapa estándar. La razón por la que no usamos un Mapa es porque en los contextos donde se usa Bundle, las únicas cosas que son legales para poner en ella son primitivas como Strings, ints, etc. Debido a que la API de mapa estándar le permite insertar objetos arbitrarios, esto permitiría a los desarrolladores poner datos en el mapa que el sistema no puede soportar, lo que conduciría a errores de aplicación raros y no intuitivos. El paquete se creó para reemplazar el mapa con un contenedor typesafe que hace explícitamente claro que sólo admite primitivas.
Una parcela es similar a un paquete, pero es más sofisticada y puede soportar la serialización más compleja de las clases. Las aplicaciones pueden implementar la interfaz Parcelable para definir clases específicas de aplicación que se pueden transmitir, especialmente cuando se utilizan Servicios. Los Parcelables pueden ser más sofisticados que los Bundles, pero esto tiene un costo considerablemente mayor.
Bundle y Parcel son ambos mecanismos de serialización de datos, y en su mayor parte ambos se utilizan cuando el código de la aplicación pasa los datos a través de los procesos. Sin embargo, debido a que la parcela es mucho más alta que Bundle, los paquetes se utilizan en los lugares más comunes como el método onCreate, donde la sobrecarga debe ser lo más baja posible. Las parcelas se utilizan con mayor frecuencia para permitir que las aplicaciones definan Servicios con API lógicas que pueden utilizar clases con significado de aplicación como argumentos de método y valores de retorno. Si requerimos un paquete allí, resultaría en APIs realmente desordenadas. En general, debe mantener las API de servicio lo más simples posible, ya que las primitivas se serializarán de manera más eficiente que las clases parcelables personalizadas.
Resuelto.
El problema era que el PNG que estaba usando no es compatible con Android. El código:
icon.getConfig()
Devuelve null.
Mientras que gt_ebuddy da una buena respuesta, sólo tengo una pequeña nota a su pregunta:
Problema: está intentando pasar un objeto Bitmap
a la memoria, puede estar bien; Sin embargo, no es bueno pasar muchos objetos de Bitmap
como este. Realmente mala práctica.
Mi solución: La imagen ya existe en resources
, tiene una ID
única; Hacer uso de ella. En lugar de intentar pasar una gran cantidad de Bitmaps
pesados, puede pasar su ID
mediante Bundle
o Parcel
, pero Bundle
es preferible para una estructura de datos sencilla.
- Instalación de un binario preinstalado en Android: "no encontrado"
- ¿Cómo pasar el enum personalizado en @Query a través de Retrofit?