在将数百个图像加载到网格时,Android应用程序的性能问题

时间:2013-02-01 11:21:39

标签: android android-sdk-2.1

我在Android中有一个针对工程行业的编目应用程序。已经有超过30万个设计图像上传到Android设备中。每天有超过200个新图像与设备同步。

有一个名为CatalogDetail的表,其中存储了设计的详细信息。它有大约20列用于存储不同的属性和两个图像路径,一个用于缩略图,另一个用于大图像。缩略图的平均大小约为20KB,大图像的平均大小约为40KB。并且所有这些图像都存储在同一文件夹中(不在数据库中)。 30万张图片的总体大小约为6GB。根据各种搜索条件,缩略图图像和简短描述显示在应用程序的网格中。

如果我在文件夹中有5000个图像,则应用程序正常工作,随着数据大小的增加,应用程序变得越来越慢。现在加载30万张图像后,当我加载250张图像(最终用户希望一次加载至少250张图像)进入网格时,加载到网格相对较慢,但是当我尝试滚动时,它需要相当多的很长时间(大约10 - 15秒),这是不可取的。

我已经分析了我的SQL并且发现SQL没有花费相当多的时间(获取数据不到1秒)。最后我发现,问题在于从文件夹加载图像。图像存储在内部存储器中。该应用程序正在使用三星Galaxy Tab 750 10.1英寸与Android 3.1(Honeycomb)操作系统,RAM 1GB和16GB内存。该应用程序是使用SDK 10开发的。 最终用户的基本要求之一是设计图像非常专有,应该从设备中复制。因此,图像文件夹是隐藏的,无法在应用程序外部访问。

请告诉我如何改善表现。
1.如果图像是索引可以提高性能吗?是否可以索引(是否有任何软件,应用程序等可用?
2.如果我在每个文件夹中保存了1000张图像,如果我创建300个文件夹并从中获取图像,是否可以提高性能?但这应该是最后一个选项,因为我要重新加载所有图像并修改表格中的图像位置 3.线程可以帮忙吗? (真诚的我不知道穿线!)

请建议我如何改善表现 谢谢你的帮助。

搜索功能将执行此方法:

private void ShowData() {
    try {
        Cursor countc = dal.getCursor("Select count(*) From Product " + whereCondition);
        SQL = "Select ID as _id, Name, Code, ProductWeight, '" + fileLoc + "' || ImageLoc as ImageLoc, ReleaseDate From CatalogDetail " + whereCondition;
        Cursor c = dal.getCursor(SQL + " Order By " + orderByField + " " + OrderSeq);

        ProductGridView.setAdapter(new CatalogueListAdapter(this, c));
    } catch (Exception e) {
        e.printStackTrace();
    }
}  

这是目录加载到网格的方式:

public class CatalogueListAdapter extends SimpleCursorAdapter {
    private Context context;
    private Cursor c;

    public CatalogueListAdapter(Context context, Cursor c) {
        super(context, R.layout.thumbnail, c, new String[] {}, new int[] {});
        this.context = context;
        this.c = c;
    }
    @Override
    public View getView(int position, View inView, ViewGroup parent) {
        View v = inView;
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.thumbnail, null);
        }
        c.moveToPosition(position);

        ImageView ivThumb = (ImageView) v.findViewById(R.id.thumbnail);
        String imageLoc = this.c.getString(this.c.getColumnIndex("ImageLoc"));
        if (imageLoc != null) 
            ivThumb.setImageURI(Uri.parse(imageLoc));
        return v;
    }
}

1 个答案:

答案 0 :(得分:0)

我自发想到的一件事就是根据他们的名字简单地将图片分发到子文件夹中,或者,如果不可能,给他们提供适合的名称。

通常,open()调用需要扫描一个名为目录的特殊文件。如果有许多条目,则此线性搜索可能变得非常慢。

如果你愿意,我的建议有点像“索引”,虽然我喜欢这里的“混合”方法。仅仅因为冒泡排序对于少数项目来说总是最快的,因为开销较少,类似的规则也适用于目录。

因此,如果图像可以通过文件名或文件名的哈希值进行分发,则使用子目录结构来放置它们。当然,均匀分布必须是这里的主要目标,因此明智地选择名称或散列函数。

总结:

  1. 是和否;见上面的文字。 ;)
  2. 是的,我更喜欢它,因为如果我的假设是正确的,那么单独使用一个额外的索引将无济于事。(
  3. 同样,如果我的假设是正确的,那么线程将无济于事。