【问题标题】:Loading Thumbnails into a Bitmap Array - best practice将缩略图加载到位图数组中 - 最佳实践
【发布时间】:2014-04-17 00:22:01
【问题描述】:

作为一个完整的 Android 新手,并且(诚然)不是最强大的程序员 - 我想就将缩略图图像加载到一个位图数组中寻求一些建议,该数组被加载到一个自定义适配器中。

缩略图非常小(大约 5KB)。

我将缩略图添加到异步任务中的位图数组。我正在使用可绘制的虚拟图像。所以我用虚拟图像加载整个列表(稍后我会加载实际图像)。

如果用户浏览包含 200 多张图片的文件夹,我会担心。我可能会遇到内存不足错误。我想要一种方法来防止这种情况,也许只加载可见显示中需要的内容,并在需要时加载更多内容?

我已经阅读了很多关于回收位图的其他问题和建议,但我仍然不确定从哪里开始。

   @Override
    protected Boolean doInBackground(DbxFileSystem... params) {
        //Opens thumbnails for each image contained in the  folder
        try {
        DbxFileSystem fileSystem = params[0];

        Bitmap image=null;

        int loopCount=0; //I use this to identify where in the adapter the real image should go
        for (DbxFileInfo fileInfo: fileSystem.listFolder(currentPath)) {

            try{

                if(!fileInfo.isFolder)
                {
                    image = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
                    pix.add(image);
                    paths.add(fileInfo.path);
                    loopCount++;

                }
                else
                {
                    //must be a folder if it has no thumb, so add folder icon
                    image = BitmapFactory.decodeResource(getResources(), R.drawable.dbfolder);
                    pix.add(image);
                    paths.add(fileInfo.path);
                    loopCount++;

                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
            System.gc();

        }

    }
    catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        loadingDialog.dismiss();
    }
    return true;
}

这是来自自定义适配器的 getView:

public View getView(final int position, View arg1, ViewGroup arg2) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);


    View v = arg1;
    ViewHolder holder;

    if (arg1 == null) {
        LayoutInflater vi = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.list_row, null);

        holder = new ViewHolder();
        holder.title = (TextView) v.findViewById(R.id.filename);
         holder.iconImage = (ImageView) v.findViewById(R.id.list_image);
        holder.checkbox = (CheckBox)v.findViewById(R.id.checkBox1);

        v.setTag(holder);
    } else {
        holder = (ViewHolder) v.getTag();
    }

        holder.title.setText(folderName.get(position).toString());


    holder.iconImage.setImageBitmap(images.get(position));

【问题讨论】:

    标签: android image bitmap


    【解决方案1】:

    您需要知道的第一件事是,当使用适配器时,视图只有在它们显示在屏幕上时才会创建。这意味着您不需要也不能解码所有位图。

    最佳做法是在创建关联视图时解码AsyncTask 中的每个位图。位图将在doInBackground 方法中解码,并在onPostExecute 方法中设置为ImageView(因为它在UI thread 上执行)。

    那么您可能还想使用 RAM 或磁盘缓存来更有效地重新加载以前解码的位图。

    请查看http://developer.android.com/training/displaying-bitmaps/index.html,了解有关如何有效显示位图的更多信息。

    【讨论】:

    • 我正在使用异步任务 - 上面的代码在 doInBackground 中。在 postExecute 中,我绑定了 Adapter,所有内容都添加到了 ListView。我将更改代码以添加完整的异步任务
    • 是的,但是您应该为单个位图创建一个 AsyncTask,它将在 getView 方法中启动,这样您就不必解码所有位图。
    • 感谢您的评论,我已经添加了我的适配器代码,这样您就可以看到我是如何设置图像的。如何告诉适配器是否加载可绘制对象?
    • 您的 AsyncTask 应该只解码一个位图。看看这条评论,它可能会启发你stackoverflow.com/questions/23106657/…
    • Asynctask 在 getView 方法中启动,解码视图所需的位图。
    猜你喜欢
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-20
    • 1970-01-01
    • 2015-09-25
    相关资源
    最近更新 更多