[RESOLVIDO]OutofMemory BitMap

E ai pessoal tudo beleza!

estou tendo um problema serio, estou fazendo download via aplicação de um numero considerável de imagens tipo umas 5000 imagens de varias dimensões todas. eu começo a baixar tá tudo tranquilo, quando eu chego em torno da imagem 1800 eu estouro o heap size do aparelho. pesquisando pela nela testei algumas soluções e vi na documentação do Android falando do Option implementando o inSampleSize, porem essa variavel diminui o tamanho da imagem, como estou usando Bitmap, já chamei o recycle(), já chamei o system.gc(), chamei os dois juntos tb, e não consigo achar uma forma de limpar o heap do aparelho para cada download, não me atenderia dimininuir o tamanhdo da imagem sendo que eu vou precisar dela do tamanho que ela é .

o problema se dá nessa ultima linha;

			ByteArrayInputStream is = new ByteArrayInputStream(tempOut.toByteArray());
			
//                     BitmapFactory.Options options = new BitmapFactory.Options();
//                     options.inSampleSize = 1;
			
			Bitmap myBitmap = BitmapFactory.decodeStream(is);

alguem sabe como isso funciona?

Utilize um profiler para identificar o seu gargalo. Lembre sempre de limpar as instancias que você esta carregando as imagens para evitar que elas fiquem em memoria.
Fiz um post a alguns dias sobre como resolvi um memory leak bem cabreiro… você pode ver aqui: www.jemiliod.blogspot.com

            ByteArrayInputStream is = new ByteArrayInputStream(tempOut.toByteArray());  
            Bitmap myBitmap = BitmapFactory.decodeStream(is);

Depois de você usar o ByteArrayInputStream, você o fecha (método close()) ?

O Garbage Collector não fecha tudo tão rapidamente quanto você quer. Se algo é aberto, deve ser fechado o mais rapidamente possível após o uso.

Em uma aplicação de camera ocorria o outOfMemory algumas vezes, diminui bem a ocorrencia utilizando o recycle, setando null para qualquer byte array utilizado e por fim chamando o gc.

Ja tentou gerar a bitmap direto do byteArray ?

Já tentei sim, ocorre a mesma coisa

Destruiu também as Views que voce as exibe? Setando images para null, recycle nos Bitmaps e setCallback(null) em Drawables?

Entao mark eu não as exibo eu faço o download e salvo no sd,

olha o codigo abaixo


System.out.println("Downloading: " + imageURL);
			HttpClient httpClient = new DefaultHttpClient();
			HttpGet httpGet = new HttpGet(URI.create(imageURL));

			//recebe a resposta
			HttpResponse httpResponse = httpClient.execute(httpGet);
			if(httpResponse.getStatusLine().getStatusCode() >= 400) {
				throw new Exception("Erro ao baixar imagem do servidor."+ httpResponse.getStatusLine().getStatusCode());
			}
			HttpEntity responseEntity = httpResponse.getEntity();
			InputStream input = responseEntity.getContent();
			byte[] buffer = new byte[1024];
			int sizeRead;
			ByteArrayOutputStream tempOut = new ByteArrayOutputStream();
			while ((sizeRead = input.read(buffer)) != -1) {
				tempOut.write(buffer, 0, sizeRead);
			}
			tempOut.flush();
			tempOut.close();
			ByteArrayInputStream is = new ByteArrayInputStream(tempOut.toByteArray());

			//            BitmapFactory.Options options = new BitmapFactory.Options();
			//            options.inSampleSize = 1;

			Bitmap myBitmap = BitmapFactory.decodeStream(is);
			//			Bitmap myBitmap = BitmapFactory.decodeStream(is, null, options);
			is.close();
			File nFile = null;
			if(myBitmap != null) {
				//verifica se o path padrao das imagens foi criado
				String path = App.IMAGE_PATH;
				File dir = new File(path+"/image");
				//se não existir cria o diretorio
				if (!dir.exists()) {
					dir.mkdir();
				}

				//a partir daqui a imagem é salva no diretorio
				nFile = new File(dir.getAbsolutePath(), fileName);
				createThumb(nFile, myBitmap);
				compressBitMap(myBitmap, nFile);

				myBitmap = null;
				System.gc();

============================================

		private void compressBitMap(Bitmap myBitmap, File nFile) throws FileNotFoundException, IOException {
			OutputStream fOut = new FileOutputStream(nFile);
			myBitmap.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
			fOut.flush();
			fOut.close();
			myBitmap.recycle();
		}

		private void createThumb(File file, Bitmap map) {
			try {
				// load the origial BitMap (500 x 500 px)
				int width = map.getWidth();
				int height = map.getHeight();

				int newWidth = 40;
				int newHeight = 40;
				if (App.SDK_VERSION >= 13) {
					newWidth = 100;
					newHeight = 100;
				}


				// calculate the scale - in this case = 0.4f
				float scaleWidth = ((float) newWidth) / width;
				float scaleHeight = ((float) newHeight) / height;

				// createa matrix for the manipulation
				Matrix matrix = new Matrix();
				// resize the bit map
				matrix.postScale(scaleWidth, scaleHeight);

				// recreate the new Bitmap
				Bitmap resizedBitmap = Bitmap.createBitmap(map, 0, 0, width, height, matrix, true);
				String pathThumb = file.getParent()+"/thumb";
				File tFile = new File(pathThumb);
				if (!tFile.exists()) {
					tFile.mkdir();
				}
				tFile = new File(tFile.getAbsolutePath()+"/"+file.getName());

				compressBitMap(resizedBitmap, tFile);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

Acredito que sejam as streams então.

como assim?

Olá
Já verificou se as 5000 imagens cabem no celular?
Já tentou retomar os dowloads a partir da última imagem baixada?

Por exemplo, sempre chame consumeContent() de HttpResponses e chame close() em Input/OutputStreams.

Se você vai apenas salvar não há necessidade de criar bitmaps (o que se deve evitar ao máximo por ser muito pesado).

Se você faz download de um servidor php:

    [code]  URLConnection ucon = url.openConnection();
      InputStream inputStream = null;
      HttpURLConnection httpConn = (HttpURLConnection)ucon;
      httpConn.setRequestMethod("GET");
      httpConn.connect();

      if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
       inputStream = httpConn.getInputStream();
      }else{
      throws new NotResponseException();
      }
        FileOutputStream fos = new FileOutputStream(file);
        int size = 1024*1024;
        byte[] buf = new byte[size];
        int byteRead;
        while (((byteRead = inputStream.read(buf)) != -1)) {
            fos.write(buf, 0, byteRead);
            bytesDownloaded += byteRead;
        }
        fos.close();[/code]

Se é um link direto (ex: www.site.com/imagem.jpg

pode usar o downloadManager
http://developer.android.com/reference/android/app/DownloadManager.html

eu uso o bitmap pra comprimir em jpg

mais apesar que se eu garantir que a imagem seja jpg do lado do servidor eu nao preciso comprimir ela.

Galera aparentemente eu resolvi. retirei todos os bitmaps do metodos e salvei direto com o FileOutput e funcionou, resolvi garantir que a imagens vai chegar do jeito que eu preciso do lado do servidor.

Valeu a todos.