RecyclerView с Glide, OOM на нескольких элементах - PullRequest
0 голосов
/ 06 февраля 2019

Я использую обзор переработчика, который происходит от базового переработчика.Это код для моего базового рециркулятора:

  abstract class BaseRecyclerAdapter<B : ViewDataBinding> : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
    open lateinit var binding: B
    private lateinit var context: Context
    private var lastPosition = 0

    fun bind(parent: ViewGroup, layout: Int): ViewHolder {
        context = parent.context
        val layoutInflater = LayoutInflater.from(parent.context)
        binding = DataBindingUtil.inflate(layoutInflater, layout, parent, false)
        return ViewHolder(binding.root)
    }

    inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    fun setAnimation(viewToAnimate: View, position: Int) {
        if (position > lastPosition) {
            val animation = AnimationUtils.loadAnimation(context, R.anim.list_animation_fall_down)
            viewToAnimate.startAnimation(animation)
            lastPosition = position
        }
    }
} 

Я расширяю этот класс из моего SearchAdapter следующим кодом:

class SearchAllAdapter(private val activity: DashboardActivity, private val returnVendors: ArrayList<Content>, private val searchVM: SearchVM, private val latLng: LatLng) : BaseRecyclerAdapter<ItemSearchAllVendorBinding>() {
    private lateinit var context: Context

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        val viewHolder = bind(parent, R.layout.item_search_all_vendor)
        binding.searchVM = searchVM
        this.context = parent.context
        return viewHolder
    }

    override fun getItemCount(): Int {
        return returnVendors.size
    }

    override fun getItemViewType(position: Int): Int {
        return position
    }

    override fun getItemId(position: Int): Long {
        return returnVendors[position].id.toLong()
    }

    @SuppressLint("SetTextI18n", "SimpleDateFormat")
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        if (!activity.hasUser) binding.ivSearchAllDeliveringFavorite.visibility = View.GONE

        val item = returnVendors[position]

        if (item.open && !Hawk.contains(Constants.CONFIGURATION_PLATFORM)) {
            val toLocation = Location("").also {
                it.latitude = item.latitude
                it.longitude = item.longitude
            }
            val fromLocation = Location("").also {
                it.latitude = latLng.latitude
                it.longitude = latLng.longitude
            }
            val distance = fromLocation.distanceTo(toLocation)
            val eta = Math(activity.app, distance, item.preparationTime).getETA(item.bufferTime)
            if (eta > 45) {
                binding.flSearchAllDeliveringEta.background = ResourcesCompat.getDrawable(context.resources, R.drawable.bg_delivery_time_accent, null)
                binding.ivSearchAllDeliveringEta.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_vendor_state_out, null))
            }
            binding.tvSearchAllDeliveringEta.text = "$eta MIN"
        } else {
            binding.flSearchAllDeliveringEta.background = ResourcesCompat.getDrawable(context.resources, R.drawable.bg_delivery_time_close, null)
            binding.ivSearchAllDeliveringEta.setImageDrawable(ResourcesCompat.getDrawable(context.resources, R.drawable.ic_vendor_state_closed, null))

            val cal = Calendar.getInstance()
            val openingCal = Calendar.getInstance()

            try {

                val openingTime = activity.app.sdf.parse(item.openAt)
                openingCal.time = openingTime

                val openingTimeFormat = SimpleDateFormat("h:mm a")
                when {
                    openingCal.get(Calendar.DATE) - cal.get(Calendar.DATE) == 0 -> binding.tvSearchAllDeliveringEta.text = context.getString(R.string.tv_closed_today) + " " + openingTimeFormat.format(openingTime)
                    openingCal.get(Calendar.DATE) - cal.get(Calendar.DATE) in 1 downTo 0 -> binding.tvSearchAllDeliveringEta.text = context.getString(R.string.tv_closed_tomorrow)
                    else -> binding.tvSearchAllDeliveringEta.text = context.getString(R.string.tv_closed_on) + " " + openingCal.getDisplayName(Calendar.DAY_OF_WEEK, Calendar.LONG, Locale.getDefault())
                }
            } catch (error: NullPointerException) {
                binding.tvSearchAllDeliveringEta.text = context.getString(R.string.label_closed)
            }
        }
        binding.cvSearchAllDeliveringContainer.tag = item
        binding.ivSearchAllDeliveringFavorite.tag = item.id
        binding.tvSearchAllDeliveringItem.text = item.name

        item.image?.let {
            when {
                !item.image.isNullOrEmpty() -> {
                    GlideApp.with(context)
                            .load(item.image)
                            .centerCrop()
                            .fitCenter()
                            .into(binding.ivSearchAllDeliveringFood)
                }

                else -> {
                    binding.ivSearchAllDeliveringFood.setImageDrawable(null)
                }
            }
        }

        val priceRange = when {
            item.priceRange == "LOW" -> String.format("\u20B1")
            item.priceRange == "MEDIUM" -> String.format("\u20B1\u20B1")
            else -> String.format("\u20B1\u20B1\u20B1")
        }

        binding.tvSearchAllDeliveringCategories.text = priceRange

        for (category in item.categories) {
            if (binding.tvSearchAllDeliveringCategories.text.isNotEmpty()) binding.tvSearchAllDeliveringCategories.text =
                    "${binding.tvSearchAllDeliveringCategories.text} • ${category.name}"
            else binding.tvSearchAllDeliveringCategories.text = category.name
        }
        setAnimation(holder.itemView, position)
    }

    override fun onViewRecycled(holder: RecyclerView.ViewHolder) {
        super.onViewRecycled(holder)
        binding.ivSearchAllDeliveringFood.setImageDrawable(null)
    }
} 

Все работает нормально, за исключением того, что после загрузки нескольких элементов яget OOM .

Главное, что я заметил в поведении, это то, что при прокрутке память продолжает расти и не падает до выделения памяти перед прокруткой.Кажется, он не перезапускает представления после того, как он больше не виден.

Разрешение изображения довольно большое, но я не думаю, что это проблема, поскольку память продолжает накапливаться после каждой прокрутки, вызывающей OOM.

Любое предложение или идея, что вызывает эту проблему?

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