Как я могу использовать код BitmapRegionDecoder в android 2.2.2 (Froyo)?

Я читал ответ на другой вопрос на SO, в котором @RomainGuy прокомментировал, что можно (пожалуйста, поправьте меня, если я перефразирую неправильно) код порта из более поздних версий android для более ранних версий. В частности, меня интересует обратный код для BitmapRegionDecoder от Android версии 2.3.3 (Gingerbread) до версии 2.2.2 (Froyo).

Я бы скорее задал вопрос в более общем плане, как наилучшая практика/чего следует избегать при обратном переносе кода из более новых версий Android в более старые версии, но stackoverflow намекнул, что мой вопрос может быть закрыт как слишком субъективный.

Возможно, если в теме будет достаточно интереса, этот вопрос может быть "превращен" в более общий. Возможно, это сообщество wiki?

В любом случае, я был бы признателен за любое понимание того, как это делается. Какой-либо конкретный для моего прецедента или более общий совет. Выполняют ли вызовы собственные методы из класса java (обязательно связаны с NDK)?

Если это действительно возможно (и разумно) для кода вишневого и обратного порта таким образом, я думаю, многим было бы очень полезно знать, как это сделать.

Ответ 1

Как отметил @hackbod BitmapRegionDecoder, на основе внешней библиотеки skia. Однако это может быть полезно.

Рассмотрим исходный источник:

  • BitmapRegionDecoder.java. В основном определяет оболочки вокруг собственных методов:

    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
    

    Класс не использует никаких новых API-интерфейсов Java, которые нам нужны для резервного копирования.

  • BitmapRegionDecoder.cpp. Заголовочные файлы включают в себя те, которые присутствуют в Froyo кроме этих двух:

    • AutoDecodeCancel.h. Единственная строка, в которой она использовалась:

      AutoDecoderCancel   adc(options, decoder);
      

      Этот класс обрабатывает жизненный цикл экземпляров SkDecoder. Это небольшая часть кода и может быть хорошо перенесена.

    • SkBitmapRegionDecoder.h

      Как указано в имени файла, это основной компонент. На самом деле все предыдущие были своего рода обертки вокруг него. Хорошей новостью является то, что нам может не потребоваться обратный перенос, поскольку можно было бы взять целую библиотеку skia из Gingerbeard и скомпилировать ее под Froyo, поскольку она является внешней и не содержит никаких новых зависимостей.

P.S. Я на самом деле не погружался глубоко в код, поэтому, пожалуйста, исправьте меня, если я ничего не упустил.

Обновление:

Исходный код, который нам нужен, находится в следующих репозиториях на ветвях froyo-release и gingerbread-mr4-release:

Ответ 2

Вы можете выполнить резервное копирование некоторого кода, если он может существовать поверх SDK, на который вы его портируете.

Вы ничего не можете вернуть. Например, вы не можете выполнить резервное копирование функции ядра.:)

В этом случае нет простого решения по его обратному переносу. Реализация этого находится поверх Skia и jpeg-декодера, которые являются и внутренним кодом. Вам нужно будет выполнить свою собственную реализацию этого кода. Вы можете попробовать скопировать/вставить код с платформы, наклеив его на свой код с помощью JNI, но это будет значительная работа и оставит вам собственный код, который вам нужно продолжать поддерживать.

Извините, для этого нет легкого решения.

Ответ 3

Вам следует рассмотреть BitmapRegionDecoderCompat, версию API 8 + стандарта BitmapRegionDecoder (API 10 +).

Функции

  • Он работает в режиме "compat" на устройствах, на которых запущен API < 10, используя базовый Java/Android fallback (что означает, что он не будет столь же эффективным и быстрым, как реализация JNI на основе API 10+, но он избежит уродливых шаблонов и ручных резервных копий).
  • использует встроенную реализацию JNI при работе на API 10 +.
  • Он добавляет дополнительные удобные методы, такие как decodeBestRegion(), который извлекает "наилучшую" субрегион изображения с учетом ваших параметров (гравитация, размер). Этот метод также работает на API < 10.

Скачать

Чтобы использовать его в своем проекте, вы можете вручную загрузить и добавить библиотеку в файл AAR:

Download

или вы можете добавить dependecy в свой build.gradle (требуется репозиторий jCenter):

dependencies {
    //...your dependecies
    compile 'org.bonnyfone:brdcompat:0.1'
}

Использование

Как указано в документах, для перехода на BRDCompat вам просто нужно изменить имя базового класса от BitmapRegionDecoder до BitmapRegionDecoderCompat:

//BitmapRegionDecoder brd = BitmapRegionDecoder.newInstance(...);
BitmapRegionDecoderCompat brd = BitmapRegionDecoderCompat.newInstance(...);