正确释放属于适配器的视图中的资源

android listview memory-leaks android-view

269 观看

2回复

6274 作者的声誉

我的列表适配器创建一些Views(正常视图和标题视图),使用不断运行的计时器来循环显示的图像。

我想知道释放那些计时器和其他视图相关资源的适当方法是什么,我的意思是,最好的做法是知道一个项目View(由其创建Adapter.getView)不再可见/需要,或者已经被回收或去除,或者甚至他们的父窗口小部件也没有被使用。

理想情况下,我在寻找一个方法/事件/监听器View,而不是父Widget必须委托一个事件。我想知道

  • View给予回收者时(即它已经退出屏幕等)
  • View可以销毁时(即 - 包含的小部件已被销毁)

到目前为止,我认为我没有找到适当的,防止失败的事件,如果有的话。

我试过View.onAttachedToWindow()/ View.onDetachedFromWindow()但是,反对onAttachedToWindow那似乎总是被恰当地称为,onDetachedFromWindow不是。它似乎仅在回收视图即将重复使用时调用,而不是在View进入回收池(退出屏幕),或者窗口小部件被破坏,甚至活动完成时等其他情况下调用

有什么建议吗?

编辑:

我一直在做一些测试,发现onDetachedFromWindow父窗口小部件上 IS可靠。目前我的解决方案是将该事件传播到适配器,然后适配器在屏幕上查找视图(getFirstVisiblePosition...)并onDetachedFromWindow使用下面的代码手动触发,但是,你知道,这非常难看。我相信有更好的方法。

// ugly function to trigger an onDetachedFromWindow to any view
// leeched from com.tonicartos.widget.stickygridheaders.StickyGridHeadersGridView
public static void detachHeader(View header) {
    if (header == null) { return; }

    try {
        Method method = View.class.getDeclaredMethod("dispatchDetachedFromWindow");
        method.setAccessible(true);
        method.invoke(header);
    } catch (NoSuchMethodException e) {
        throw new RuntimePlatformSupportException(e);
    } catch (IllegalArgumentException e) {
        throw new RuntimePlatformSupportException(e);
    } catch (IllegalAccessException e) {
        throw new RuntimePlatformSupportException(e);
    } catch (InvocationTargetException e) {
        throw new RuntimePlatformSupportException(e);
    }
}
作者: rupps 的来源 发布者: 2014 年 12 月 5 日

回应 (2)


0

1439 作者的声誉

RecyclerView.Adapter有一种方法可以在回收视图时通知您。看一下

public void onViewRecycled(RecyclerView.ViewHolder holder);

作者: Andrew Kelly 发布者: 13.10.2016 11:51

0

158 作者的声誉

a)离开活动 - 冲洗adpater中的所有内容

可能正确的方法是使用onStop周围活动的方法。你有一个适配器的引用。在适配器中,您可以提供flushAllResources()从活动中调用的方法。这适用于离开活动的情况。

@Override
public void onViewRecycled(@NonNull final MyViewHolder holder) {
    flushAllViewRefreshHandlers();
}

b)由于滚动,视图将被重复使用 - 在视图被使用前冲洗旧数据

此外,在onViewRecycled方法中(如前所述),您还应该刷新资源。这适用于将要为其他实体重复使用(回收)回收商的单个项目/视图的情况。在这种情况下,您可能只刷新特定视图/实体的数据,而不是整个适配器的所有数据。

作者: Kaspatoo 发布者: 29.01.2019 01:42
32x32