【问题标题】:App lags with android:layerType="software"应用程序滞后于 android:layerType="software"
【发布时间】:2014-07-05 23:01:37
【问题描述】:

我正在制作一个非常简单的应用程序(基本上是一个只有几张图片的列表视图)。它通常在我的测试设备上表现得非常好(摩托罗拉 Moto G 附带的股票 android)。

但是,我希望我的 ListView 有虚线分隔线。因此,我创建了一个 list_divider.xml 文件来定义分隔符并将其设置为要在 ListView 中使用的分隔符。我已经在我的 Moto G 上尝试过,但它没有显示虚线。

所以我四处搜索并找到here 解决问题的方法。禁用视图的硬件加速解决了错误并正确显示了分隔线。

但是,现在我遇到了另一个问题:由于禁用硬件加速,应用在滚动时开始滞后。

是否有解决方案来使用虚线分隔线而不禁用硬件加速,或者至少具有与禁用它之前几乎一样好的性能?

编辑:这是我使用的适配器代码:

public class AstronautArrayAdapter extends ArrayAdapter<Astronaut> {

    public static final String TAG = "AstronautArrayAdapter";

    public AstronautArrayAdapter(Context context, List<Astronaut> objects) {
        super(context, R.layout.astronauts_list_row, objects);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        RowViewHolder holder = null;
        if (convertView == null) {
            LayoutInflater inflater = ((Activity) getContext()).getLayoutInflater();
            convertView = inflater.inflate(R.layout.astronauts_list_row, parent, false);

            holder = new RowViewHolder();
                holder.name = (TextView) convertView.findViewById(R.id.nameOfAustronaut);
            holder.daysInSpace = (TextView) convertView.findViewById(R.id.numberOfDaysInSpace);
            holder.country = (ImageView) convertView.findViewById(R.id.countryImage);
            holder.title = (TextView) convertView.findViewById(R.id.titleOfAstronaut);

            convertView.setTag(holder);
        } else {
            holder = (RowViewHolder) convertView.getTag();
        }

        Astronaut astronaut = getItem(position);

        holder.name.setText(astronaut.getName());
        holder.daysInSpace.setText(Integer.toString(astronaut.getDaysInSpace()));
        holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));
        holder.title.setText(astronaut.getTitle());

        return convertView;
    }

    private static class RowViewHolder {
        TextView name;
        TextView daysInSpace;
        ImageView country;
        TextView title;
    }

}

编辑 2:这是有问题的两个布局文件:

activity_main.xml

<ListView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/astronautsList"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" 
    android:padding="16dp"
    android:dividerHeight="3dp"
    android:divider="@drawable/list_divider"
    android:layerType="software" />

list_divider.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="line" >

    <stroke
        android:width="1px"
        android:color="@android:color/black"
        android:dashWidth="5px"
        android:dashGap="1px" />

    <size android:height="3dp" />

</shape>

【问题讨论】:

  • 那一行:holder.country.setImageBitmap(astronaut.getCountryImage(getContext())); 让它看起来像你可能在 UI 线程上进行位图解码(甚至下载)。你是吗??
  • 没有。在应用程序开始时,我下载我想要的所有内容并将其保存在本地。 (该应用程序在开始时确实滞后,但我知道这是因为下载而需要它)。
  • “本地保存”这仍然意味着在该行调用期间,位图正在从磁盘读取(I/O 操作)和解码(CPU 密集型操作)。我会在答案中写下我的建议。

标签: android listview hardware-acceleration


【解决方案1】:

您看到的滞后的可能答案是:

dependencies 部分中的这一行添加到您的 build.gradle 中

compile 'com.squareup.picasso:picasso:2.3.2'

并替换这一行

holder.country.setImageBitmap(astronaut.getCountryImage(getContext()));

Picasso.with(context).load(/* insert the URL here */).into(holder.country);

并删除下载所有图像并在本地保存的代码。 Picasso 会自动下载/解码位图并为您管理磁盘和内存缓存。

ps.:

如果您不使用 Gradle:

  1. 您应该切换到 Android-Studio 并使用 Gradle
  2. 忘记我所说的将行添加到 gradle 文件中,只需从他们的 website 下载 jar 文件,放入 libs 文件夹并确保弄乱项目设置以确保 jar 进入你的 APK(老实说,我不记得这些设置是如何工作的,因为我很久以前就放弃了 Eclipse)

【讨论】:

  • Re #2:把它放在libs 中,ADT 会为你做这件事,幸运的是 Google 并没有那么放弃 ADT
【解决方案2】:

正如你没有提到的,你实现了 ViewHolder 模式吗?

当 ListView 回收视图时,它必须膨胀布局并在其中插入任何文本和图像。您通常在这部分代码中调用 findViewById,这非常昂贵。 ViewHolder 模式解决了这个问题并且很容易实现。

在此处查看 Google 提供的精彩教程

http://developer.android.com/training/improving-layouts/smooth-scrolling.html

【讨论】:

  • 是的,我确实使用了 ViewHolder,但它仍然滞后。
  • 使内部类静态
  • 你不需要私有的,否则代码看起来不错可能需要布局文件来确定。
  • 我会添加它,请稍等;)
  • 好吧,看到其他cmets去抢这个叫做Picasso的库,它真的很简单,并且处理图像加载非常好square.github.io/picasso
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-29
  • 1970-01-01
  • 2020-05-31
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2012-04-18
相关资源
最近更新 更多