#android #jpeg #out-of-memory
#Android #jpeg #не хватает памяти
Вопрос:
Моя первоначальная проблема заключалась в том, что я загружал файл jpeg размером 1,3 МБ и устанавливал его в качестве изображения. Это привело к исключениям нехватки памяти. По-видимому, теперь сервер изменяет размер фотографии перед ее загрузкой. Однако я все еще получаю ожидания от ООМ. Какой самый простой способ измерить размер загружаемого файла?
РЕДАКТИРОВАТЬ Я должен также упомянуть, что это отлично работает на эмуляторе, но падает при запуске на G1
public Drawable getImage() throws IOException, MalformedURLException {
InputStream is = (InputStream) new java.net.URL(url).getContent();
return Drawable.createFromStream(is, "name");
}
Комментарии:
1. вы имеете в виду размер диска или потребляемую память после визуализации изображения?
2. Я хочу выяснить, что вызывает исключение ООМ, так что, я думаю, либо
Ответ №1:
Важны размеры загружаемого вами изображения. Объем используемой памяти будет примерно равен ширине * высоте * 2 байтам (или * 4 байтам, если изображение загружено в 32 бита). BitmapFactory предоставляет способ считывания размеров изображения без загрузки всего изображения. Вы могли бы использовать это, чтобы увидеть, насколько большим будет изображение в памяти перед его загрузкой.
Ответ №2:
Если вы делаете это с помощью streams, у каждого дочернего элемента Stream (например, InputStream) есть метод read, который возвращает количество прочитанных байтов. Просто посчитайте эти байты, и вы получите размер вашего изображения. Вот небольшой пример кода:
while ((count = is.read(data)) != -1) {
out.write(data, 0 , count);
}
Удачи!
Комментарии:
1. спасибо за это, но я не могу понять, как включить это в свой код. Не могли бы вы мне помочь? Я добавил свой код выше @Egor
2. Инициализируйте массив байтов «данные» и считайте входящие в него байты из вашего входного потока, используя этот код. Затем создайте извлекаемый файл из этого массива байтов. Надеюсь, я правильно это объяснил.
Ответ №3:
Исключения из ООМ, вероятно, происходят из-за того, что вы не перерабатываете создаваемые вами растровые объекты. При рендеринге изображения (я предполагаю, в ImageView) вы, вероятно, захотите сделать что-то вроде этого:
ImageView iv;
// before you update the imageview with the image from the server
if(iv.getDrawable() != null) ((BitmapDrawable)iv.getDrawable()).getBitmap().recycle();
Комментарии:
1. Я получаю только 1 изображение за действие. Итак, если я запущу эту переработку до получения изображения, я бы ничего не перерабатывал. Прав ли я, думая об этом?
2. Что ж, будьте осторожны там. 1 изображение за действие не означает, что вы не создаете несколько растровых изображений. В зависимости от вашего пути к коду вы можете повторно раздувать изображение из файла и устанавливать режим рисования в ImageView. Если вы делаете это, вам все равно нужно будет сделать что-то подобное, иначе у вас закончится память. Я бы рекомендовал поместить
android.util.Log
оператор в вашуdrawImage()
функцию: если он вызывается несколько раз, то вам определенно нужно что-то подобное.3. Я думал, что у меня что-то получилось с Android, но теперь я чувствую себя не в своей тарелке. Я не вызываю метод drawImage(). Я создаю новый ImageView, используя объект рисования, возвращаемый вышеуказанным методом. Я совершенно потерян, поэтому я действительно ценю вашу помощь
4. Важнейшая часть вашей проблемы с ООМ заключается в том, что если эта функция вызывается несколько раз, у вас быстро закончится память, потому что она создает несколько выводимых файлов. Итак, первый шаг — проверить, сколько раз это вызывается, и использовать ли
recycle()
функцию для освобождения используемой памяти ПЕРЕД созданием новой.5. Возможно davidjhinson.wordpress.com/2010/05/19 /…