Android - sposób na cache obrazków

Data publikacji: 2011-12-13 , Wyświetleń: 1556

android cache logo Rozkmina o tym jak można by cache'ować obrazki w systemie android. Tego typu rzeczy zawsze zajmują sporo czasu przy pierwszym poejściu do zagadnienia.

 

1. Gdzie trzymać obrazki?

W środowisku Android mamy do wyboru 2 rozsądne miejsca. 

  1. Pamięć cache aplikacji (zazwyczaj jest to katalog /data/data/[app.name]/cache)
  2. Karta SD urządzenia

W pierwszym przypadku mamy do dyspozycji zazwyczaj trochę szybszą pamięć danych ale za to ograniczoną rozmiarem. Pamięci wewnętrzne nie są zbyt duże a ich rozmiar wyrażany jej zazwyczaj w megabajtach niż w gigabajtach. Także tutaj to trzymać będzie można (jak napisane jest na stronach dokumentacji) około 1 MB danych.

 

Inny wymiar przestrzeni do wykorzystania mamy w przypadku karty SD urządzenia. Tutaj jest to zazwyczaj już parę gigabajtów do zagospodarowania.

 

2. Pobieramy i zapisujemy

Kolejny krok to proces pobrania pliku oraz jego zapis. Procedura jest prosta:

private Bitmap downloadImage(String url, File localFile) {
	Bitmap res = null;
	try {
		URL u = new URL(url);
		URLConnection connection = u.openConnection();
		if (localFile.exists()){
			// jeżeli plik istnieje to do nagłowka doklejamy
			// datę ostatniej modyfikacji 
			connection.setIfModifiedSince(localFile.lastModified());
		}
		// wyłączamy cache
		connection.setUseCaches(false);

		if (connection.getContentLength() > 0) {
			// zapis na karcie SD/cache
			InputStream is = (InputStream) connection.getContent();
			FileOutputStream out = new FileOutputStream(localFile);
			try {
				byte[] buffer = new byte[1024];
				int bufferLength = 0;
				while ( (bufferLength = is.read(buffer)) > 0 ) {
					out.write(buffer, 0, bufferLength);
				}
				out.close();
			} catch (IOException e) {
				// blad IO
			}
			// ustawiamy datę modyfikację na taką jaka jest na serwerze
			localFile.setLastModified(connection.getLastModified());
		} else {
			// serwer nie zwrócił nic 
			//(data pliku na serwerze jest taka sama jak na urządzeniu)
		}
		res = BitmapFactory.decodeFile(localFile.getAbsolutePath());
	} catch (Exception e) {
		// ogólny wyjątek
	}
	return res;
}

Wszystko odbywa sę wg. schematu:

  1. sprawdzenie czy istnieje plik na karcie SD/cache
  2. jeżeli istnieje do nagłówka doklejamy nagłówek IfModifiedSince
  3. wyłączamy cache systemowy
  4. jeżeli rozmiar zwróconych danych jest większy niż 0 to zapisujemy plik na karcie SD/cache
  5. na koniec tworzymy bitmapę z pliku

Powstać może pytanie: Po co wyłączamy systemowy cache?

Jeżeli ten parametr ustawimy na true to dane będą zapisywane w cache pamięci aplikacji (getCacheDir) przez co mamy ograniczony rozmiar przestrzenie do przechowania danych. W taki sposób mamy większą kontrolę nad danymi.

W praktyce to wystarczy oudować przedstawioną powyżej funkcję klasą od obsługi cache (jakaś tablica z elementami Bitmap) i mamy gotowe rozwiązanie.

Tagi: android, java, cache