I have an adapter class that is being used to populate the recyclerview item with cardviews. This RecyclerView is located under a fragment. Inside this adapter, I am trying to bind an image to a imageview which is under the cardview layout. I am trying to achieve that under the following method which is in the adapter class:
public void onBindViewHolder(@NonNull ProductViewHolder holder, int position) {
Product product = myProducts.get(position);
holder.productTitle.setText(product.getProductName());
holder.productDesc.setText(product.getDescription());
Uri uri = Uri.parse(product.getImageUri());
Glide.with(/*WHAT SHOULD I PASS HERE??*/).load(new File(uri.getPath())).into(holder.productImage);
}
Each product instance has a field which contains path to an image and I want to take that path, find corresponding image and draw it in the cardview item. But I have no idea what should I pass to Glide.with()
as an argument. Thanks in advance and please point out anything seems wrong. I am very novice in android programming.
Edit: Following is the holder class.
class ProductViewHolder extends RecyclerView.ViewHolder {
private ImageView productImage;
private TextView productTitle;
private TextView productDesc;
public ProductViewHolder(View itemView) {
super(itemView);
productImage = itemView.findViewById(R.id.product_image);
productTitle = itemView.findViewById(R.id.product_title);
productDesc = itemView.findViewById(R.id.product_desc);
}
}
And I have tried this
Glide.with(holder.itemView).load(new File(uri.getPath())).into(holder.productImage);
But it gave an error like this:
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There were 3 causes:
java.io.IOException(File unsuitable for memory mapping)
java.io.FileNotFoundException(/document/msf:24: open failed: ENOENT (No such file or directory))
java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
This is my adapter class:
public class ProductAdapter extends RecyclerView.Adapter<ProductAdapter.ProductViewHolder> {
private final LayoutInflater myInflater;
private List<Product> myProducts = new ArrayList<>();
private Context context;
public ProductAdapter(Context context) {
this.context = context;
myInflater = LayoutInflater.from(context);
}
@NonNull
@Override
public ProductViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = myInflater.inflate(R.layout.card_view_product, parent, false);
return new ProductViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull ProductViewHolder holder, int position) {
Product product = myProducts.get(position);
holder.productTitle.setText(product.getProductName());
holder.productDesc.setText(product.getDescription());
Uri uri = Uri.parse(product.getImageUri());
Glide.with(context).load(new File(uri.getPath())).into(holder.productImage);
}
@Override
public int getItemCount() {
return myProducts.size();
}
public void setProducts(List<Product> products) {
myProducts = products;
notifyDataSetChanged();
}
class ProductViewHolder extends RecyclerView.ViewHolder {
private ImageView productImage;
private TextView productTitle;
private TextView productDesc;
public ProductViewHolder(View itemView) {
super(itemView);
productImage = itemView.findViewById(R.id.product_image);
productTitle = itemView.findViewById(R.id.product_title);
productDesc = itemView.findViewById(R.id.product_desc);
}
}
}
And the error
W/Glide: Load failed for /document/msf:25 with size [384x384]
class com.bumptech.glide.load.engine.GlideException: Failed to load resource
There were 3 causes:
java.io.IOException(File unsuitable for memory mapping)
java.io.FileNotFoundException(/document/msf:25: open failed: ENOENT (No such file or directory))
java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
call GlideException#logRootCauses(String) for more detail
Cause (1 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.nio.ByteBuffer, LOCAL
There was 1 cause:
java.io.IOException(File unsuitable for memory mapping)
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class java.io.IOException: File unsuitable for memory mapping
Cause (2 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class java.io.InputStream, LOCAL
There was 1 cause:
java.io.FileNotFoundException(/document/msf:25: open failed: ENOENT (No such file or directory))
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class java.io.FileNotFoundException: /document/msf:25: open failed: ENOENT (No such file or directory)
Cause (3 of 3): class com.bumptech.glide.load.engine.GlideException: Fetching data failed, class android.os.ParcelFileDescriptor, LOCAL
There was 1 cause:
java.io.FileNotFoundException(open failed: ENOENT (No such file or directory))
call GlideException#logRootCauses(String) for more detail
Cause (1 of 1): class java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
I/Glide: Root cause (1 of 3)
java.io.IOException: File unsuitable for memory mapping
at com.bumptech.glide.util.ByteBufferUtil.fromFile(ByteBufferUtil.java:38)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:61)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
I/Glide: Root cause (2 of 3)
java.io.FileNotFoundException: /document/msf:25: open failed: ENOENT (No such file or directory)
at libcore.io.IoBridge.open(IoBridge.java:496)
at java.io.FileInputStream.<init>(FileInputStream.java:159)
at com.bumptech.glide.load.model.FileLoader$StreamFactory$1.open(FileLoader.java:142)
at com.bumptech.glide.load.model.FileLoader$StreamFactory$1.open(FileLoader.java:139)
at com.bumptech.glide.load.model.FileLoader$FileFetcher.loadData(FileLoader.java:71)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:66)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
at libcore.io.Linux.open(Native Method)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at libcore.io.BlockGuardOs.open(BlockGuardOs.java:252)
at libcore.io.ForwardingOs.open(ForwardingOs.java:167)
at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7255)
at libcore.io.IoBridge.open(IoBridge.java:482)
at java.io.FileInputStream.<init>(FileInputStream.java:159)
at com.bumptech.glide.load.model.FileLoader$StreamFactory$1.open(FileLoader.java:142)
at com.bumptech.glide.load.model.FileLoader$StreamFactory$1.open(FileLoader.java:139)
at com.bumptech.glide.load.model.FileLoader$FileFetcher.loadData(FileLoader.java:71)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:66)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
I/Glide: Root cause (3 of 3)
java.io.FileNotFoundException: open failed: ENOENT (No such file or directory)
at android.os.ParcelFileDescriptor.openInternal(ParcelFileDescriptor.java:315)
at android.os.ParcelFileDescriptor.open(ParcelFileDescriptor.java:220)
at com.bumptech.glide.load.model.FileLoader$FileDescriptorFactory$1.open(FileLoader.java:166)
at com.bumptech.glide.load.model.FileLoader$FileDescriptorFactory$1.open(FileLoader.java:163)
at com.bumptech.glide.load.model.FileLoader$FileFetcher.loadData(FileLoader.java:71)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.FileLoader$FileFetcher.loadData(FileLoader.java:76)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.onDataFetcherFailed(DecodeJob.java:408)
at com.bumptech.glide.load.engine.SourceGenerator.onLoadFailedInternal(SourceGenerator.java:160)
at com.bumptech.glide.load.engine.SourceGenerator$1.onLoadFailed(SourceGenerator.java:83)
at com.bumptech.glide.load.model.ByteBufferFileLoader$ByteBufferFetcher.loadData(ByteBufferFileLoader.java:66)
at com.bumptech.glide.load.engine.SourceGenerator.startNextLoad(SourceGenerator.java:70)
at com.bumptech.glide.load.engine.SourceGenerator.startNext(SourceGenerator.java:63)
at com.bumptech.glide.load.engine.DecodeJob.runGenerators(DecodeJob.java:310)
at com.bumptech.glide.load.engine.DecodeJob.runWrapped(DecodeJob.java:279)
at com.bumptech.glide.load.engine.DecodeJob.run(DecodeJob.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at java.lang.Thread.run(Thread.java:919)
at com.bumptech.glide.load.engine.executor.GlideExecutor$DefaultThreadFactory$1.run(GlideExecutor.java:393)
I debug the code to see does the path of an image returns successfully and it does. But it is not showing up in the list item. I think there is nothing wrong in the part where addition process happens.
you need to pass the context of your activity/fragment which contains the image view in the with()
.
you can achieve this by passing the context of your activity in your adapter constructor. for example, your Adapter constructor might look like that:
myAdapter(Context context, List<Object> dataset) {
this.context = context;
...
...
}
and when you create an instance from the adapter you can pass the context like this:
myAdapter adapter = new MyAdapter(this,...);
then you can use the context for Glide like this:
Glide.with(context)
I hope this helps, if you need more clarifications, let me know in the comments!