Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
31 |
Tags
- appcompatactivity
- 상태관리
- viewModelScope
- 절대 주소
- appcompatacitivity
- 플로이드워셜
- Kotlin
- Android
- apk 빌드 과정
- NestedScrollView
- AAC
- http발전과정
- 운영체제
- 뷰홀더
- 자이고트
- http 역사
- GetX
- Dispatchers
- flutter
- DiffUtil
- 안드로이드
- 데코레이터 패턴
- AsyncListDiffer
- 디자인 패턴
- 물리 메모리
- 리사이클러뷰풀
- 프로세스
- 내부 단편화
- 리사이클러뷰
- recyclerview
Archives
- Today
- Total
hong's android
[안드로이드] Lru Cache 본문
Lru Cache(Least Recently Used Cache) 란?
가장 오랫동안 참조되지 않은 값(노드)을 삭제하고 비교적 최근에 참조된 값(노드)들을 저장하는 캐시 방식
Double Linked List를 기본적으로 사용한다. Head에 가까운 노드일수록 최근에 참조된 노드, tail에 가까울수록 참조가 오랫동안 되지 않은 노드이다. 만약 정해진 cache size가 초과된 상황에서 노드(값)를 추가할 때 tail에 가장 가까운 노드가 삭제되고, 새로운 참조 노드가 head에 가깝게 추가된다.
안드로이드에선 Lru Cache방식을 사용하기 위한 관련 클래스를 제공한다.
캐시 크기 설정시 주의점
모든 애플리케이션에 적합한 특정 크기나 수식은 없으며 사용량을 분석하여 적합한 해결책을 찾아야 합니다. 캐시가 너무 작으면 아무런 이점 없이 추가 오버헤드가 발생하고 캐시가 너무 크면 또다시 java.lang.OutOfMemory 예외가 발생하여 앱의 나머지 부분에 사용할 메모리가 거의 남아 있지 않을 수 있습니다.
비트맵 캐싱 | Android 개발자 | Android Developers
단일 비트맵을 사용자 인터페이스(UI)에 로드하는 것은 간단하지만 한 번에 더 큰 이미지의 집합을 로드해야 하면 더 복잡해집니다. 많은 경우(ListView, GridView 또는 LruCache 클래스와 같은 구성요소
developer.android.com
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var memoryCache : LruCache<String, Bitmap>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initCache()
binding.button.setOnClickListener {
loadBitmap("https://picsum.photos/200",binding.imageView)
}
}
fun initCache(){
// Get max available VM memory, exceeding this amount will throw an
// OutOfMemory exception. Stored in kilobytes as LruCache takes an
// int in its constructor.
val maxMemory = (Runtime.getRuntime().maxMemory() / 1024).toInt()
// Use 1/8th of the available memory for this memory cache.
val cacheSize = maxMemory / 8
memoryCache = object : LruCache<String, Bitmap>(cacheSize) {
override fun sizeOf(key: String, bitmap: Bitmap): Int {
// The cache size will be measured in kilobytes rather than
// number of items.
return bitmap.byteCount / 1024
}
}
}
fun loadBitmap(url: String, mImageView: ImageView) {
val bitmap: Bitmap? = memoryCache.get(url)?.also {
mImageView.setImageBitmap(it)
Log.d("image","From memory")
} ?: run {
Log.d("image","From internet")
val task = BitmapWorkerTask()
task.setImageView(mImageView)
task.execute(url)
null
}
}
private inner class BitmapWorkerTask : AsyncTask<String, Unit, Int>() {
private lateinit var mImageView : ImageView
private var bmp: Bitmap? = null
fun setImageView(imageview: ImageView) {
mImageView = imageview
}
// Decode image in background.
override fun doInBackground(vararg params: String?): Int {
var url = params[0]
try {
bmp = getBitmapFromURL(url)
if(bmp != null){
memoryCache.put(url,bmp)
Log.d("image","save image to cache")
}
} catch (e : Exception) {
e.printStackTrace()
0
}
return 1
}
override fun onPostExecute(result: Int) {
if(result == 1){
mImageView.setImageBitmap(bmp)
}
super.onPostExecute(result)
}
private fun getBitmapFromURL(url: String?): Bitmap? {
return try {
val url = URL(url)
val connection: HttpURLConnection = url.openConnection() as HttpURLConnection
connection.setDoInput(true)
connection.connect()
val input: InputStream = connection.getInputStream()
BitmapFactory.decodeStream(input)
} catch (e: IOException) {
e.printStackTrace()
null
}
}
}
}
처음 이미지 load
같은 이미지 다시 load
'Android > Android' 카테고리의 다른 글
[안드로이드] Appcompatactivity은 어떻게 뷰 호환성을 유지할까? (4) | 2024.11.14 |
---|---|
[안드로이드] DiffUtil (0) | 2023.02.21 |
[안드로이드] RecyclerView (0) | 2023.02.14 |
[안드로이드] Appcompatactivity (0) | 2023.02.14 |
[안드로이드] apk 빌드 과정 (+ DVM,ART) (0) | 2023.02.11 |