android UI 在某些设备上滞后

android UI lag on some devices

我有一个 android 项目,其中包含 viewpager 和导航抽屉。在 viewpager 的每个片段中,我都有一个 gridview,其中包含来自服务器的加载数据!我的问题是,从低硬件到功能强大的所有设备,一切都运行良好,但在某些设备(如 galaxy s4 和某些 sony xperia)中,它在滚动 gridview 或打开导航抽屉时会产生太多延迟。怎么了?

P.S: 下面是 gridview 适配器的代码:

public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        convertView = inflater.inflate(R.layout.grid_item, parent, false);
    }
    SimpleData item = myDatas.get(position);
    ((TextView) convertView.findViewById(R.id.title)).setText(item.getName());
    ImageView thumbnail = (ImageView) convertView.findViewById(R.id.thumbnail);
    thumbnail.getLayoutParams().height = thumbnail.getLayoutParams().width;

    if (item.getThumbnail() != null && !item.getThumbnail().isEmpty()) {
        if (item.getThumbnail().startsWith("http")) {
            Picasso.with(mContext)
                    .load(item.getThumbnail())
                    .placeholder(R.drawable.loading)
                    .into(thumbnail);
        } else {
            Picasso.with(mContext)
                    .load(Uri.fromFile(new File(item.getThumbnail())))
                    .placeholder(R.drawable.loading)
                    .into(thumbnail);
        }
    } else {
        thumbnail.setImageResource(R.drawable.noimage);
    }

    ((TextView) convertView.findViewById(R.id.province)).setText(item.getProvince());
    ((TextView) convertView.findViewById(R.id.likesCount)).setText(item.getLikesCount() + "");

    convertView.forceLayout();
    return convertView;
}

你正在做很多这里不推荐的事情,这可能是你滞后的原因。

首先不要使用 convertView.forceLayout();,根据其 documentation 它会在不需要时强制呈现您的布局。其次,您给 convertView 充气,您应该 而不是 在适配器的 getView 中这样做。请记住,您正在覆盖 class 并且扩充布局不是您的工作,它由上层的适配器 class 自动完成。

最后你没有使用以下形式的适配器设计模式:

if (convertView == null) {
  ...
} else {
  ...
}

有关后者的更多信息,请参考 this documentation,有一个 ImageAdapter 示例。

你的 getView 方法做了很多事情,你应该学习如何在 GridView 中加载位图 asynchronously 之后它不会滞后。

终于找到问题了!滞后是因为代码的其他部分在 UI 线程上设置图像,在 Line:

下面
 thumbnail.setImageResource(R.drawable.noimage);

所以我将 "noimage" 可绘制对象替换为压缩对象并更改此行以使用 Picasso 加载文件,如下所示,一切正常。

 Picasso.with(mContext)
                .load(R.drawable.noimage)
                .placeholder(R.drawable.loading)
                .into(thumbnail);

感谢大家的帮助。