Для моих 10 000 пунктов я решил что-то обсудить с этим классным сайтом: механизм кэширования растровых изображений в собственной памяти.
Фон
У Android-устройств очень ограниченный объем памяти для каждого приложения - диапазон от 16 МБ до 128 МБ, в зависимости от различных параметров.
Если вы пройдете этот предел, вы получите OOM, и это может произойти много раз, когда вы используете растровые изображения.
Во многих случаях для приложения может потребоваться преодолеть эти ограничения, выполнить тяжелые операции с огромными растровыми изображениями или просто сохранить их для последующего использования, и вам нужно
То, что я придумал, - это простой класс java, который упростит для этих целей вещи.
Он использует JNI для хранения данных растрового изображения и может восстановить его при необходимости.
Чтобы поддерживать несколько экземпляров класса, мне пришлось использовать трюк, который я нашел ( здесь).
Важные примечания
-
Данные все еще хранятся в ОЗУ, поэтому, если на устройстве не хватает ОЗУ, приложение может быть убито.
-
Не забудьте освободить память, как только сможете. это не только для предотвращения утечек памяти, но и для того, чтобы избежать приоритета системы, которую нужно убить первым, после того, как ваше приложение заходит на задний план.
-
Если вы не хотите забывать освободить память, вы можете либо освободить ее каждый раз при восстановлении растрового изображения, либо сделать реализацию класса Закрывается.
-
В качестве меры безопасности я автоматически освободил свою собственную память в методе finalize(), но не позволяю ей отвечать за работу. это слишком рискованно. я также сделал запись в журнал, когда такое происходит.
-
Как это работает, копируя все данные в объекты JNI, и для восстановления он создает растровое изображение с нуля и помещает данные внутри.
-
Растровые изображения, используемые и восстановленные, находятся в формате ARGB_8888. конечно, вы можете изменить его на все, что пожелаете, просто не забудьте изменить код...
-
Большие битовые карты могут занять время для хранения и восстановления, поэтому было бы разумно сделать это в фоновом потоке.
-
Это не полное решение OOM, но оно может помочь. например, вы можете использовать его в сочетании с вашим собственным LruCache, избегая при этом использования кучной памяти для самого кэша.
-
Код предназначен только для хранения и восстановления. если вам нужно выполнить некоторые операции, вам нужно будет провести некоторое исследование. openCV может быть ответом, но если вы хотите выполнить некоторые основные вещи, вы можете реализовать их самостоятельно ( здесь пример для ротации больших изображений с использованием JNI). если вы знаете другие альтернативы, сообщите мне, здесь.
Надеюсь, это будет полезно для некоторых людей. напишите свои комментарии.
Кроме того, если вы обнаружите какую-либо проблему с кодом или предложением о перемещении, сообщите мне.
Лучшее решение
Если вы хотите выполнить еще больше операций со стороны JNI, вы можете использовать этот пост, который я сделал. он основан на коде, который я написал здесь, но позволяет вам делать больше операций, и вы можете легко добавить больше своих собственных.