본문 바로가기
개발 공부 기록하기/- Android

Glide 메모리 줄이고 사이즈는 유지시키기

by soulduse 2018. 6. 10.
반응형

보통 RecyclerView안에 사진이 있을경우 Glide를 사용해서 이미지 처리를 했었는데


한번에 보여줘야할 이미지들이 많은경우 메모리가 폭발하는 현상이 발생했다.


메모리를 많이 잡아먹으니 간헐적으로 OOM이 발생하는게 아닌가 ㅠㅠ



뜨억.... 앱 시작시 여러 데이터를 한번에 받아오니 메모리가 터지기 일보직전인 상황.


대략 화면의 구성은 다음과 같은데

ViewPager안에 뷰가 4개가 있는데 전부 로드해서 들고 있다.

그런데 4개의 뷰에는 각각 RecyclerView가 포함되어있고 이미지가 엄청많이 들어가 있는상황.


저러니 메모리가 530MB가량 차지하는것을 볼 수 있다..


도대체 얼마나 큰 이미지이길래? 저렇게 많이 차지하는지 확인해보자.

override fun onBindViewHolder(holder: RepositoryHolder, position: Int) {

items[position].let {repo ->

with(holder){
GlideApp.with(holder.itemView.context)
.load(repo.imageUrl)
.listener(createLoggerListener("original"))
.into(weather_item_iv)

weather_item_title.text = repo.title
}
}
}

private fun createLoggerListener(name: String): RequestListener<Drawable> {
return object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?,
model: Any?,
target: com.bumptech.glide.request.target.Target<Drawable>?,
isFirstResource: Boolean): Boolean {
return false
}

override fun onResourceReady(resource: Drawable?,
model: Any?,
target: com.bumptech.glide.request.target.Target<Drawable>?,
dataSource: DataSource?,
isFirstResource: Boolean): Boolean {
if (resource is BitmapDrawable) {
val bitmap = resource.bitmap
Log.d("GlideApp",
String.format("Ready %s bitmap %,d bytes, size: %d x %d",
name,
bitmap.byteCount,
bitmap.width,
bitmap.height))
}
return false
}
}
}

Glide에서 이미지가 로드될때 리스너를 추가하여 이미지 대한 정보를 출력하도록 하였다.


ㅠㅠ 말도 안되는 큰용량의 이미지들이 엄청많이 한번에 로드 되고 있는것이 확인되었다.


우선 메모리 확보를 위해 용량을 줄여보자

GlideApp.with(holder.itemView.context)
.load(repo.imageUrl)
.listener(createLoggerListener("original"))
.override(200, 200)
.into(weather_item_iv)

Glide 옵션중 override( size, size )를 사용해서 

기존에 1440 x 1440이미지를 극단적으로 200 x 200으로 줄여보았다.


오... 많이 줄었다 그래프를 보면?


529MB > 259MB 약 270MB가 감소되었다. 


그런데 한가지 문제가 발생했는데

이미지가 200x200으로 축소되는게 아닌가..!

<ImageView
android:id="@+id/weather_item_iv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scaleType="fitCenter"
tools:src="@drawable/ic_crab_50px" />

사용되고 있는 ImageView에  scaleType을 fitCenter를 줘도 크기 조정이 되지 않았다.

<ImageView
android:id="@+id/weather_item_iv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
tools:src="@drawable/ic_crab_50px" />

이럴 경우에는! 

adjustViewBounds를 사용하도록 하자.


구글 개발자 홈페이지에서 찾아보면 true 값을 줬을경우, ImageView 종횡비 조절을 유지시켜준다고 되어있다.

따라서 200 x 200으로 작아진 이미지도 기존에 설정된 layout_width 크기가 유지되니 이미지 화질은 떨어지지만 원래의 크기에 맞춰서 

화면이 잘 출력되는 것을 확인 할 수 있다. 너무 화질이 떨어져도 안되니 적당히 조정해서 쓰자.


추가로 혹시나 저와 같이 viewPager안에 메모리를 잡아먹는 요소들이 너무많은 경우에는 

UI를 새로 구성해봐도 좋고, 그게 아니라면 ViewPager로드를 얼마만큼 할 것인지 잘 정해서 활용해보는 것도 좋다.


이상으로 포스팅 끝!

반응형