首页 > 解决方案 > 滚动RecyclerView时Android Picasso图像加载应用程序崩溃

问题描述

我正在使用 Retrofit 访问此 Web 服务链接:

https://jsonplaceholder.typicode.com/photos

在不加载图像的情况下在 recyclerview 中加载项目时,该应用程序运行良好。但是,如果我添加毕加索代码来加载图像,应用程序会在滚动 2 或 3 次后崩溃。

我收到以下错误:

A/Looper: Could not make wake event fd: Too many open files

或将这些错误全部放在一起:

E/Parcel: fcntl(F_DUPFD_CLOEXEC) failed in Parcel::read, i is 0, fds[i] is -1, fd_count is 1, error: Too many open files

E/EGL_emulation: tid 11410: swapBuffers(552): error 0x300d (EGL_BAD_SURFACE)

A/Looper: Could not make wake event fd: Too many open files

E/NativeCrypto: AppData::create pipe(2) failed: Too many open files

这是导致问题的唯一代码:

我首先在 Adapter 构造函数中设置它:

Picasso.Builder builder = new Picasso.Builder(context);
builder.downloader(new OkHttp3Downloader(context));

这就是 RecyclerView 的 onBind() 中的毕加索代码

public void onBindViewHolder(CustomViewHolder holder, int position) {
        holder.txtTitle.setText(dataList.get(position).getTitle());

      ---------------------------------------------------------
        builder.indicatorsEnabled(true);
        builder.build().load(dataList.get(position).getThumbnailUrl())
                .placeholder((R.drawable.ic_launcher_background))
                .error(R.drawable.ic_launcher_background)
                .into(holder.coverImage);
      ----------------------------------------------------------

    }


这是改造代码:

  RetrofitServiceInterface service = RetrofitClient.getRetrofitInstance().create(RetrofitServiceInterface.class);
        Call<List<RetroPhoto>> call = service.getAllPhotos();
        call.enqueue(new Callback<List<RetroPhoto>>() {
            @Override
            public void onResponse(Call<List<RetroPhoto>> call, Response<List<RetroPhoto>> response) {
                progressDoalog.dismiss();
                generateDataList(response.body());
            }

            @Override
            public void onFailure(Call<List<RetroPhoto>> call, Throwable t) {
                progressDoalog.dismiss();
                Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
                Log.e("error",t.getMessage());
            }
        });
    }
    /*Method to generate List of data using RecyclerView with custom adapter*/
    private void generateDataList(List<RetroPhoto> photoList) {
        recyclerView = findViewById(R.id.customRecyclerView);
        adapter = new CustomAdapter(this,photoList);
        RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(adapter);
    }

这是完整的 RecyclerView 适配器代码:

public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {

    private List<RetroPhoto> dataList;
    private Context context;
    Picasso.Builder builder;

    public CustomAdapter(Context context,List<RetroPhoto> dataList){
        this.context = context;
        this.dataList = dataList;

        builder = new Picasso.Builder(context);
        builder.downloader(new OkHttp3Downloader(context));
        builder.indicatorsEnabled(true);

    }

    class CustomViewHolder extends RecyclerView.ViewHolder {

        public final View mView;

        TextView txtTitle;
        private ImageView coverImage;

        CustomViewHolder(View itemView) {
            super(itemView);
            mView = itemView;

            txtTitle = mView.findViewById(R.id.title);
            coverImage = mView.findViewById(R.id.coverImage);
        }
    }

    @Override
    public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
        View view = layoutInflater.inflate(R.layout.custom_row, parent, false);
        return new CustomViewHolder(view);
    }

    @Override
    public void onBindViewHolder(CustomViewHolder holder, int position) {
        holder.txtTitle.setText(dataList.get(position).getTitle());

        builder.build().load(dataList.get(position).getThumbnailUrl())
                .placeholder((R.drawable.ic_launcher_background))
                .error(R.drawable.ic_launcher_background)
                .into(holder.coverImage);

    }

    @Override
    public int getItemCount() {
        return dataList.size();
    }
}

标签: androidandroid-recyclerviewretrofit2android-imageviewpicasso

解决方案


推荐阅读