ListView与TableLayout使用的Android内存

时间:2012-10-10 07:03:01

标签: android listview memory tableview consumption

为了减少我的应用程序的总堆大小,我试图将TableLayout更改为ListView。

源列表是一个ArrayList,其中包含drawble,text和checkbox状态。此数组事先已完全初始化。

在使用ListView或TableLayout打开活动之前,堆大小约为7.5Mb

使用TableLayout,它增长到8.3Mb并且不会增长 使用ListView,它最初增长到8.1Mb,滚动列表时增长到11.5Mb!

为什么ListView在滚动时消耗更多,而它应该重用视图? 我期待ListView在使用滚动时消耗更少,实际上不会增长!?

我看到的行为是正常的还是预期的,还是我错过了什么?

我已经验证了ListAdapter确实重用了视图,这里是ListAdapter代码的摘录。它包含getView()方法中唯一的new()。

private static class AppListAdapter implements ListAdapter
{
    WeakReference<MyActivity>   wr;
    ArrayList<AppInfo>      app_list;

    public AppListAdapter(MyActivity activity, ArrayList<AppInfo> list)
    {
        wr = new WeakReference<at_startup_apps>(activity);
        app_list = list;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        MyActivity activity = wr.get();
        if (sa == null)
            return null;

        AppInfo ai = app_list.get(position);

        LinearLayout ll;
        ImageView img;
        TextView new_txt;
        CheckBox cb;
        if (convertView == null)
        {
            ll = new LinearLayout(activity);

            img = new ImageView(sa);
            img.setScaleType(ScaleType.FIT_CENTER);
            ll.addView(img);

            new_txt = new TextView(activity);
            new_txt.setOnClickListener(activity.onTextClick);
            new_txt.setGravity(Gravity.CENTER_VERTICAL);
            new_txt.setPadding(4, 2, 4, 2);
            new_txt.setTextSize(activity.font_size + 2);
            ll.addView(new_txt);

            cb = new CheckBox(sa);
            ll.addView(cb);
        }
        else
        {
            Log.d(at_data.TAG, "Reusing view " + position);
            ll = (LinearLayout)convertView;
            img = (ImageView)ll.getChildAt(0);
            new_txt = (TextView)ll.getChildAt(1);
            cb = (CheckBox)ll.getChildAt(2);
        }
        ll.setId(position);

        img.setImageDrawable(ai.drawable);

        new_txt.setText(ai.name);

        new_txt.setId(position);

        cb.setOnCheckedChangeListener(null);
        if (!ai.frozen)
            cb.setChecked(true);
        cb.setOnCheckedChangeListener(sa.onCheckedListener);

        cb.setId(position);

        return ll;
    }

1 个答案:

答案 0 :(得分:3)

所以我决定测试5个测试设备上的行为,每次测试都进行了两次以确保结果的准确性。

从结果我会说ListView只有在要显示足够的项目时才能提高性能和内存消耗。对于300或更低,它似乎对任何改进都没有用。

除此之外,无论是在表现还是消费方面,收益都是立即可见的。

Iconia A500是滚动时ListView消耗更多的唯一设备。不知道为什么,但任何结果都令人放心;)

在Nexus ListView上似乎没有效果,但无法重做测试或测试更多项目。

在S3上,不确定发生了什么,但是应用肯定会消耗很多东西!

所有这些都无法解决我的初始问题:保存堆内存空间,而我的列表很少高于300(安装了所有应用程序)。

测试HW加速开/关,结果没有差异。

Iconia A500 4.0.3:列表包含180个项目

TableLayout: it grows to 8.9Mb, 8.8Mb allocated
ListView: it grows to 8.3Mb, 8.2Mb allocated and then to 12.6Mb / 10.3 when scrolling!

TF700 4.0.3:列表包含160个项目

TabletLayout: 11.9Mb / 11.8Mb
ListView: 11.3Mb / 10.1Mb

Galaxy S3 JB 4.1:列表包含365个项目

TableLayout: 20.7 / 19.8
ListView: 19.1 / 18.3

Galaxy Nexus JB 4.1:列表包含185个项目

TableLayout: to 11Mb
ListView: to 13Mb

Galaxy S 2.3.6:列表包含205个项目

TabletLayout: 6.4 / 3.8
ListView: 6.0 / 3.4

一些测试项目数量增加10倍 显然TableLayout初始化起来很慢:几秒钟!

Galaxy S 2.3.6:列表包含2050个项目

TabletLayout: 14.6 / 11.9
ListView: 6.0 / 3.4

Galaxy S3 JB 4.1:列表包含3650项

TableLayout: 20.7 / 19.8
ListView: 19.3 / 18.4

Iconia A500 4.0.3:列表包含1800个项目

TableLayout: 17.1 / 16.9
ListView: 8.1 / 7.9 then growing to 10.8 / 10.6 when scrolling