问题
I am using Retrofit to access this Webservice link:
https://jsonplaceholder.typicode.com/photos
When loading the items in a recyclerview without loading images, the app works fine. However, if I add Picasso code to load the images, the app crashes after scrolling 2 or three times.
I get the following error:
A/Looper: Could not make wake event fd: Too many open files
OR these errors all together:
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
Here's the only code that causes problems:
I first set this in the Adapter constructor:
Picasso.Builder builder = new Picasso.Builder(context);
builder.downloader(new OkHttp3Downloader(context));
And that's the picasso code in the onBind() of the RecyclerView
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);
----------------------------------------------------------
}
Here is the Retrofit code:
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);
}
And Here's the full RecyclerView Adapter Code:
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();
}
}
来源:https://stackoverflow.com/questions/52869627/android-picasso-image-loading-app-crash-when-scrolling-recyclerview