ListView的优化

ListView的优化。
[1]在布局文件中定义一个listview

<ListView
        android:id="@+id/lv_haha"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    </ListView>

[2]在主方法里面获取控件

 ListView lv = (ListView)findViewById(R.id.lv_haha);

[3]新建一个内部类MyAdapter继承自BaseAdapter

private class MyAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            return 1000000000;
        }

        @Override
        public Object getItem(int position) {
            return null;
        }

        @Override
        public long getItemId(int position) {
            return 0;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView tv = new TextView(getApplicationContext());
            tv.setText("YOUNGFORYOU");
            Log.d("SecondTest","创建一个新的TextView对象"+position);
            return tv;
        }

        @Override
        public CharSequence[] getAutofillOptions() {
            return new CharSequence[0];
        }
    }

重写方法getCount()和 getView(),前者的作用是设置要展示的listview的行数(同时也是getView()方法执行的次数),后者则是用来将数据展示在屏幕上。通过观察getView中的方法可以发现,每当执行一次getView方法,就会创建一个TextView对象,执行1000次就创建了1000次TextView的对象。部署完程序下滑列表观察日志如下:

D/SecondTest: 创建一个新的TextView对象3911
D/SecondTest: 创建一个新的TextView对象3910
D/SecondTest: 创建一个新的TextView对象3909
D/SecondTest: 创建一个新的TextView对象3908
D/SecondTest: 创建一个新的TextView对象3907
D/SecondTest: 创建一个新的TextView对象3906
D/SecondTest: 创建一个新的TextView对象3905
D/SecondTest: 创建一个新的TextView对象3904
D/SecondTest: 创建一个新的TextView对象3903
D/SecondTest: 创建一个新的TextView对象3902
D/SecondTest: 创建一个新的TextView对象3901

当创建了太多对象的时候,内存可能会不足,就产生内存溢出问题。因此,接下来我们就对这个问题进行优化。
首先观察一下API中的getView方法:
在这里插入图片描述
(网易翻译)Parameters列表中的第二个参数convertView中的Note:在使用前,您应该检查此视图是否为非空且类型是否适当。如果无法转换此视图以显示正确的数据,则此方法可以创建新视图。
其实这个参数就是用来判断是否有历史缓存,如果有的话我们就不需要在创建新的对象,直接取出来使用就OK了。代码如下:

 private class MyAdapter extends BaseAdapter{
        @Override
        public int getCount() {
            return 1000;
        }
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            TextView tv;
            if(convertView == null){
                Log.d("MainActivity","创建新的TextView对象——————"+position);
                tv = new TextView(getApplicationContext());
                return tv;
            }else{
                Log.d("MainActivity","复用历史缓存的TextView对象——————"+position);
                tv = (TextView) convertView;
            }
            tv.setText("哈哈哈——————"+position);
            return tv;
        }
    }

[1]首先判断一下convertView是否为null;
[2]如果是null的话,就创建新的对象;
[3]否则就使用历史缓存;
[4]最后将View类型的参数tv返回。
[5]在if语句块里面添加了两个打印日志,如果走的是true条件就在日志中输出:
“创建新的TextView对象——————”+position
走的false条件输出:
“复用历史缓存的TextView对象——————”+position
下面部署程序观察日志:

D/MainActivity: 创建新的TextView对象——————17
D/MainActivity: 创建新的TextView对象——————18
D/MainActivity: 创建新的TextView对象——————19
D/MainActivity: 创建新的TextView对象——————20
D/MainActivity: 创建新的TextView对象——————21
D/MainActivity: 创建新的TextView对象——————22
D/MainActivity: 创建新的TextView对象——————23
D/MainActivity: 创建新的TextView对象——————24
D/MainActivity: 复用历史缓存的TextView对象——————25
D/MainActivity: 复用历史缓存的TextView对象——————26
D/MainActivity: 复用历史缓存的TextView对象——————27
D/MainActivity: 复用历史缓存的TextView对象——————28
D/MainActivity: 复用历史缓存的TextView对象——————29
D/MainActivity: 复用历史缓存的TextView对象——————30
D/MainActivity: 复用历史缓存的TextView对象——————31
D/MainActivity: 复用历史缓存的TextView对象——————32
0-24这25行都创建了新的对象,而之后的全都是复用历史缓存。其实也就是每个组25,依次循环。第25个对应第1个创建的对象,第26个对象第2个。。。以此类推。这样就避免了创建太多新的对象导致内存溢出。从而也就实现了对ListView的优化。
当我们滑动屏幕的时候,假如你滑到了第26行,那么第1行就看不见了。Android回收机制就回把第1行的view对象回收并暂存在convertView中,再继续往下滑滑到27行时,convertView中已经有了一个view对象,那么就不需要再创建了,直接使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值