【发布时间】:2019-11-13 17:46:19
【问题描述】:
您好,我正在编写一个使用许多 customView(父级作为 FrameLayout 持有活动的上下文)的应用程序。
在应用程序中有一个 recyclerView,它的持有者拥有 N(非常多)的视图(自定义)。
由于视图的数量是动态添加的(我正在测试 10k+ 视图)。
在回收器视图中,我没有做任何特别的事情,而是使用协程,因此 10k 视图的渲染不会阻塞 Main Thread
但是由于每个 RecyclerView Holder 中有大量的 View,当我滚动时它会非常快地填满应用程序的堆内存并导致 OOM(内存不足)崩溃。
为了解决这个问题,我阅读并发现我可以对 视图。但我没有找到任何示例或参考这种方法。所以 我不确定在 Android 视图上使用 WeakReference 是否很好 解决与否。
代码和演示项目参考如下。
RecyclerView Adapter:
override fun onBindViewHolder(holder: ViewPageHolder, position: Int) {
val slideViewMultipleCanvas = SlideViewMultipleCanvas(context)
holder.slideViewItemHolder.addView(slideViewMultipleCanvas)
holder.positionHolder = position
val childJob = launch {
//this is where 10k+ view's are created
slideViewMultipleCanvas.setNumOfObjects(numOfItemsInViewPage)
slideViewMultipleCanvas.startJob()
}
map[position] = childJob
}
CustomView:
...
...
suspend fun setNumOfObjects(numberOfObjects: Int) {
withContext(Dispatchers.Default) {
for (i in 0 until numberOfObjects) {
// To solve OOM as number of view here in heap are >10k
listOfObject.add(WeakReference(ShapeView(context)))
}
}
}
...
...
private fun addViewInScope(): Boolean {
for (shapeView in listOfObject) {
shapeView.get()?.let {
addView(it)
}
}
return true
}
....
....
在使用我的测试中的 WeakReference 之后,到目前为止我还没有遇到任何问题(NO OOM's),但是每当GC(Garbage Collector) 启动并收集所有弱引用时,我仍然会得到 Lag。
我主要担心的是
- 有没有其他方法可以在不使用 WeakReference 的情况下处理大量视图的创建?
- 如果我对视图使用弱引用,会有什么问题吗?
- 如何减少 GC 延迟?(即使使用 WeakReference 我也无法平滑滚动)
附: : 我已经在处理了:
- 如果 GC 收集的是弱引用的视图,则为 null 情况
- 在 RecyclerView 中回收视图时取消协程作业。(我也可以释放此 ViewHolder 的弱引用视图吗???)
【问题讨论】:
标签: java android kotlin garbage-collection kotlin-coroutines