连续调用ArrayAdapter getView

时间:2018-01-24 18:06:52

标签: android listview android-asynctask

我有listview,其中显示了一些images。为了避免UI阻止,我试图在thumbnails中使用asyncTask延迟加载adapter,因为这似乎是我在SO上找到的最佳解决方案。

listView还有一个onItemclick和一个onItemLongClick听众。

出于某种原因,我的应用程序变得非常慢,尤其是在执行onlongclick操作后。我发现不寻常的唯一事情是我的ListView在循环中调用getView方法,从不停止。

一些代码:

适配器

public class FotoGridAdapter extends ArrayAdapter {
    private Context context;
    private int layoutResourceId;
    private ArrayList<WorkorderPicture> workorderPictures = new ArrayList<WorkorderPicture>();

    public FotoGridAdapter(Context context, int layoutResourceId, List<WorkorderPicture> pictures) {
        super(context, layoutResourceId, pictures);
        this.layoutResourceId = layoutResourceId;
        this.context = context;
        this.workorderPictures = new ArrayList<>(pictures);
    }

    @Override
    @Nullable
    public WorkorderPicture getItem(int position) {
        return workorderPictures.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View row = convertView;
        ViewHolder holder;

        if (row == null) {
            LayoutInflater inflater = ((Activity) context).getLayoutInflater();
            row = inflater.inflate(layoutResourceId, parent, false);
            holder = new ViewHolder();
            holder.imageTitle = row.findViewById(R.id.text);
            holder.image = row.findViewById(R.id.image);
            row.setTag(holder);
        } else {
            holder = (ViewHolder) row.getTag();
        }

        WorkorderPicture workorderPicture = workorderPictures.get(position);
        if (workorderPicture != null) {
            String text = workorderPicture.getTITLE();
            if (workorderPicture.getPHOTODATE() != null) {
                text += " - ";
                text += new SimpleDateFormat("dd/MM/yyyy", Locale.getDefault()).format(workorderPicture.getPHOTODATE());
            }
            holder.imageTitle.setText(text);
            String format = AttachmentUtils.getExtensionFromFileName(workorderPicture.getFILE_NAME_WITH_EXTENSION());
            if (format == null)
                format = "default";
            switch (format.toLowerCase()) {
                case "image/jpeg":
                case "image/png":
                    if (workorderPicture.getPHOTOSTREAM() != null) {
                        new ImageGridHandler(context, holder.image, workorderPicture.getPHOTOSTREAM(), workorderPicture.getPHOTOSTREAM().length).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
//                        holder.image.setImageBitmap(sbm);
                    } else {
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                            holder.image.setImageDrawable(getContext().getDrawable(R.drawable.ic_image));
                        } else {
                            holder.image.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_image));
                        }
                    }
                    break;
                case "application/pdf":
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        holder.image.setImageDrawable(getContext().getDrawable(R.drawable.ic_pdf));
                    } else {
                        holder.image.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_pdf));
                    }
                    break;
                default:
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
                        holder.image.setImageDrawable(getContext().getDrawable(R.drawable.ic_empty_image));
                    } else {
                        holder.image.setImageDrawable(getContext().getResources().getDrawable(R.drawable.ic_empty_image));
                    }
                    break;

            }

        }
        return row;
    }

    static class ViewHolder {
        TextView imageTitle;
        ImageView image;
    }

    class ImageGridHandler extends AsyncTask<String, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewReference;
        private Context context;
        private byte[] photoStream;
        private int length;

        public ImageGridHandler(Context context, ImageView img, byte[] photoStream, int length) {
            imageViewReference = new WeakReference<>(img);
            this.context = context;
            this.photoStream = photoStream;
            this.length = length;
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            Bitmap bm = BitmapFactory.decodeByteArray(photoStream, 0, length);
            return ThumbnailUtils.extractThumbnail(bm, 80, 100);

        }

        @Override
        protected void onPostExecute(Bitmap result) {
            final ImageView imageView = imageViewReference.get();
            if (imageView != null) {
                imageView.setImageBitmap(result);
                FotoGridAdapter.this.notifyDataSetChanged();
            }
            this.cancel(true);
        }
    }
}

监听

    gridView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener()
    {
        @Override
        public boolean onItemLongClick(AdapterView<?> adapterView, View view,
                                       final int position, long l) {
            AlertDialog.Builder builder = new AlertDialog.Builder(getContext(), R.style.myAlertDialogTheme)
                    .setNegativeButton("Annulla", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            dialogInterface.dismiss();
                        }
                    })
                    .setPositiveButton("Elimina", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int i) {
                            final String wpID = openedIntervention.getWorkorderPictures().get(position).getID();
                            realm.executeTransactionAsync(new Realm.Transaction() {
                                @Override
                                public void execute(Realm realm) {
                                    realm.where(WorkorderPicture.class).equalTo("ID", wpID).findFirst().setDELETED(true);
                                }
                            }, new Realm.Transaction.OnSuccess() {
                                @Override
                                public void onSuccess() {
                                    openedIntervention.setWorkorderPictures(realm.where(WorkorderPicture.class)
                                            .equalTo("WORKORDER_ID", openedIntervention.getWorkorder()
                                                    .getID())
                                            .equalTo("DELETED", false)
                                            .findAll());

                                    loadData();
                                }
                            }, new Realm.Transaction.OnError() {
                                @Override
                                public void onError(Throwable error) {

                                }
                            });
                        }
                    }).setTitle(app_name)
                    .setMessage("Eliminare l'allegato selezionato?");
            builder.show();
            return true;
        }
    });

    gridView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, final int position,
                                long id) {
          //code to show a preview
        }});

另一个信息可能是我使用Realm,但我的图片与之无关,所以我认为不重要

1 个答案:

答案 0 :(得分:2)

AsyncTask是异步的,每次完成任务后,您都会通知适配器导致数据更改事件,所以

@Override
protected void onPostExecute(Bitmap result) {
    final ImageView imageView = imageViewReference.get();
    if (imageView != null) {
        imageView.setImageBitmap(result);
        // FotoGridAdapter.this.notifyDataSetChanged();
        // ^^^^^^^^^^^^^^^^ remove this
        // not required in case of change in imageview
    }
    this.cancel(true);
}