Исключение нехватки памяти для String, StringBuffer и StringBuilder в Android - PullRequest
1 голос
/ 26 сентября 2011

Я сталкиваюсь с исключением из-за нехватки памяти при преобразовании 1,8-мегабайтного изображения в байты и последующем шифровании, и, наконец, преобразовании в строку (длина, напечатанная в журнале, составляет 1652328).А затем я добавляю эту строку в какой-то формат XML, чтобы опубликовать там, где возникает настоящая проблема.При добавлении некоторых тегов к этой pictureString с использованием StringBuffer или StringBuilder или добавлении к строке Out of Memory происходит исключение .Как решить эту проблему?

Для небольших изображений эта проблема не реплицируется.

Приведенный ниже фрагмент кода преобразует изображение по пути path в String.

fis = new FileInputStream(path);
buffer = new byte[fis.available()];
try {
    fis.read(buffer, 0, buffer.length);
    String byteString = 
        com.mobile.android.components.Base64.encodeBytes(buffer);
    return byteString;
} catch (IOException ex) {

}

Приведенное выше byteString добавляется в сообщение XML следующим образом.

StringBuilder pictureName = new StringBuilder();
pictureName.append(byteString ); //here array out of bound at StringBuilder.extendBuffer
..........
appending continues

ОБНОВЛЕНО

В приведенном выше добавлении кодированный byteStreamшифруется с использованием шифра AES и затем добавляется к StringBuilder.

Ответы [ 2 ]

1 голос
/ 26 сентября 2011

Вызовите bitmap.recycle();, как только вы преобразовали растровое изображение в байтовый массив.Это освободит собственный объект, связанный с этим растровым изображением, и очистит ссылку на данные пикселей.

Обновление

Очевидно, что фрагмент памяти, считанный из файлового потока, слишком велик для обработки.Старайтесь не читать весь файл сразу.Делай это по частям.Добавьте строку в xml без использования промежуточного строкового объекта.

Обновление 2

Вы можете сделать что-то подобное, чтобы избежать загрузки всего XML-файла при отправке его на сервер.

// Allow Inputs & Outputs
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);

// Enable POST method
connection.setRequestMethod("POST");

outputStream = new DataOutputStream( connection.getOutputStream() );
// Read file
bytesRead = fileInputStream.read(buffer, 0, bufferSize);

while (bytesRead > 0)
{
    outputStream.write(buffer, 0, bufferSize);
    bytesAvailable = fileInputStream.available();
    bufferSize = Math.min(bytesAvailable, maxBufferSize);
    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
}

Затем написать ограничивающие символы, очистить изакрыть потоки.

0 голосов
/ 10 октября 2011

Спасибо всем за поддержку.

Я наконец-то максимально оптимизировал свой код, используя файловые операции.

Для кодирования я использовал Base64.encodeFileToFile(picturePath, encodedPicturePath); Я сохранил закодированное изображение в файле.А затем для шифрования я использовал CypherOutPutStream, где FileOutputStream передается в конструктор. Так что шифрование также выполняется с использованием файла.Последний шаг при использовании HttpPost, я использовал для отправки всего зашифрованных данных как StringEntity, что является окончательным барьером для OutOfMemeoryException. Я изменил StringEntity на FileEntity. Это уменьшило потребление кучи моего приложения и таким образом улучшилоОбщая производительность и емкость загрузки.

Примечание. Не зашифровывайте закодированное изображение кусками, что приведет к изменению общих закодированных данных. Делайте это одним куском.

Сбои: перед тем, как использовать файлы дляКодируя, я разбил изображение на части и закодировал в файл. Но, если я декодирую закодированный файл, мне не удалось получить исходное изображение.

С уважением, Ша

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...