【菜鸟学安卓】- ScrollView嵌套ListView的问题 OOM

时间:2022-08-11 22:40:32

ScrollView嵌套ListView时会有一个问题,就是ListView只会显示一个item,ListView同时也失去了滑动的功能。


对于此问题的答案

第一种是在setAdapter之后重写高度,

第二种是重写ListView,我一般是采用这种,代码如下:

public class NoScrollListView extends ListView{
public NoScrollListView(Context context, AttributeSet attrs){
super(context,attrs);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec){
int mExpandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, mExpandSpec);
}
}

这种方法是把整个ListView都显示了出来,但Listview的功能却被屏蔽了,ListView本身是为了节省内存空间的,在ListView的显示中只显示了11个View,听说的。


也就是说当显示的view移出屏幕之后,ListView会自动回收掉,所以在adapter的getView中才会判断convertView是否存在,然后重新利用起来,节省内存空间。


但上面的方法却失去了这种作用,把ListView的高度全部显示了出来,当View移出屏幕之后,其实却没有被回收,这样问题就来了。


本人在不断的往ListView里加载更多的单元时,高度就在不断的加大,内存就在不断的变大,当里面存在很多图片时这时就会产生OOM,内存溢出问题。


在发现内存溢出问题时,本人在查找的过程中当然不会先想到这个问题,以为是图片过多的问题,所以就先用软引用图片,SoftReference<Bitmap> 但是问题仍然存在,后面查找过程中终于想到了这种问题的原因,由于是软引用的内容是被强应用所引用的对象,也就是说ListView中的View由于没有被清除,它是个强引用,而这个View又引用了软引用的图片,所以这个软引用的图片就不可能被回收,这样内存就得不到释放,自然就溢出了。


后来想在Adapter的getView中进行设置,就是进行判定,当显示位置的View在屏幕内的时候,就设置View里面的值,反之,不在屏幕内的view 就不引用内容 ,这样内容不被引用的话,内存过大时,JVM就是对软引用的资源进行回收,不过还不知道这个position位置与屏幕关系的判断,所以也算问题还没有解决吧。(这个好像行不通,在滑动的过程中根本就没有调用过这个方法,原因ListView已经被重写高度,根本就没移出去)


总结来说,这个ScrollView 嵌套ListView的方法可能真的不适合,所以google才会不提倡这种布局方式吧。