java - ndk - ¿Cómo puedo usar el código BitmapRegionDecoder en Android 2.2.2(Froyo)?
android ndk r17b (3)
Estaba leyendo una respuesta a una pregunta diferente en SO, en la que @RomainGuy comentó que uno podría (por favor, corríjame si estoy parafraseando incorrectamente) el código de puerto posterior de versiones posteriores de Android a versiones anteriores. Específicamente, estoy interesado en el código de portabilidad para BitmapRegionDecoder desde la versión de Android 2.3.3 (Gingerbread) a la versión 2.2.2 (Froyo).
Hubiera preferido formular la pregunta de manera más general, ya que es la mejor práctica / lo que debería evitarse cuando se transfiere el código de versiones más recientes de Android a versiones anteriores, pero Stackoverflow insinuó que mi pregunta podría cerrarse por ser demasiado subjetiva.
Tal vez si hay suficiente interés en el tema, esta pregunta podría "transformarse" en una más general ... ¿posiblemente una wiki comunitaria?
En cualquier caso, agradecería cualquier información sobre cómo se hace esto ... ya sea específica para mi caso de uso, o un consejo más general. ¿Las llamadas a métodos nativos desde dentro de la clase java complican el asunto (implicando necesariamente al NDK)?
Si de hecho es posible (y razonable) el código de selección y puerto de esta manera, creo que a muchos les resultará muy útil saber cómo.
Debería considerar BitmapRegionDecoderCompat , una versión API 8+ del BitmapRegionDecoder estándar (API 10+).
Caracteristicas
- Funciona en modo "compat" en dispositivos que ejecutan API <10 usando un respaldo básico de Java / Android (lo que significa que no será tan eficiente / rápido como la implementación JNI nativa de API 10+, pero evitará repetitivos feos y manual) fallbacks).
- Utiliza la implementación de JNI nativo cuando se ejecuta en API 10+ .
- Agrega métodos usuales adicionales como
decodeBestRegion()
, que extrae la subregión de "mejor" imagen según sus parámetros (gravedad, tamaño). Este método también funciona en API <10.
Descargar
Para utilizarlo en su proyecto, puede descargar y agregar manualmente la biblioteca como un archivo AAR :
o puede agregar la dependencia en su build.gradle (requiere el repositorio jCenter ):
dependencies {
//...your dependecies
compile ''org.bonnyfone:brdcompat:0.1''
}
Uso
Como se indica en los documentos, para migrar a BRDCompat solo necesita cambiar el nombre de la clase base de BitmapRegionDecoder
a BitmapRegionDecoderCompat
:
//BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(...);
BitmapRegionDecoderCompat brd = BitmapRegionDecoderCompat.newInstance(...);
Puede hacer una copia de respaldo de algún código, si puede existir sobre el SDK al que lo está transfiriendo.
No puedes respaldar nada. Por ejemplo, no puede realizar una copia de respaldo de una función del kernel. :)
En este caso, no hay una solución fácil para hacer un back-port. La implementación de esto se encuentra sobre Skia y el decodificador jpeg, que son ambos códigos nativos. Tendrá que hacer su propia implementación de ese código. Puede intentar copiar / pegar el código de la plataforma, pegarlo con su código con JNI, pero esto será una cantidad significativa de trabajo y lo dejará con el código nativo que necesita para seguir manteniendo.
Lo siento, no hay una solución fácil para esto.
Como @hackbod mencionó, BitmapRegionDecoder
se basa en una biblioteca skia
externa. Sin embargo, puede ser un beneficio.
Examinemos la fuente original:
BitmapRegionDecoder.java
. Principalmente define envoltorios alrededor de métodos nativos:private static native Bitmap nativeDecodeRegion(int lbm, int start_x, int start_y, int width, int height, BitmapFactory.Options options); private static native int nativeGetWidth(int lbm); private static native int nativeGetHeight(int lbm); private static native void nativeClean(int lbm); // ...multiply nativeNewInstance overloads follow
La clase no utiliza ninguna nueva API de Java que necesitaríamos para backport.
BitmapRegionDecoder.cpp
. Los archivos de encabezado que incluye constan de los que están presentes enFroyo
excepto estos dos:AutoDecodeCancel.h
. La única línea en la que se usa:AutoDecoderCancel adc(options, decoder);
Esta clase maneja el ciclo de vida de las instancias de
SkDecoder
. Es un pequeño trozo de código y puede ser bien portado.SkBitmapRegionDecoder.h
Como el nombre de archivo indica, este es un componente central. De hecho, todos los anteriores eran una especie de envoltorios a su alrededor. La buena noticia es que es posible que no necesitemos un puerto
Gingerbeard
, ya que debería ser posible tomar una bibliotecaskia
completa deGingerbeard
y compilarla bajoFroyo
ya que es externa y no contiene nuevas dependencias.
PD. En realidad, no profundicé en el código así que por favor corrígeme si hay algo que pase por alto.
Actualizar:
El código fuente que necesitamos se encuentra en los siguientes repositorios en las ramas froyo-release
y gingerbread-mr4-release
:
- Repositorio externo de la biblioteca skia
- Los archivos de encabezado están en
include/core
einclude/images
- Los archivos de encabezado están en
- Base de android
- Código de Java:
graphics/java/android/graphics/BitmapRegionDecoder.java
- Código nativo:
core/jni/android/graphics/...
- Código de Java: