【问题标题】:Using Glide Library with a Fragment adapter使用带有片段适配器的 Glide 库
【发布时间】:2020-04-29 02:32:06
【问题描述】:

我有一个适配器类,用于用卡片视图填充 recyclerview 项目。这个 RecyclerView 位于一个片段下。在这个适配器内部,我试图将图像绑定到 cardview 布局下的 imageview。我正在尝试通过适配器类中的以下方法来实现这一点:

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);
}

每个产品实例都有一个包含图像路径的字段,我想采用该路径,找到相应的图像并将其绘制在卡片视图项中。但我不知道我应该将什么传递给Glide.with() 作为参数。在此先感谢,请指出任何似乎有问题的地方。我是android编程的新手。

编辑:以下是持有者类。

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);
    }

}

我已经试过了

Glide.with(holder.itemView).load(new File(uri.getPath())).into(holder.productImage);

但它给出了这样的错误:

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))

这是我的适配器类:

 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);
        }

    }
}

还有错误

    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)

我调试代码看看图像的路径是否成功返回,并且确实如此。但它没有显示在列表项中。我认为添加过程发生的部分没有任何问题。

【问题讨论】:

    标签: java android android-glide


    【解决方案1】:

    您需要在with() 中传递包含图像视图的活动/片段的上下文。

    您可以通过在适配器构造函数中传递活动的上下文来实现此目的。 例如,您的 Adapter 构造函数可能如下所示:

    myAdapter(Context context, List<Object> dataset) {
                this.context = context;
                ...
                ...
                   }
    

    当你从适配器创建一个实例时,你可以像这样传递上下文:

    myAdapter adapter = new MyAdapter(this,...);
    

    那么你可以像这样使用 Glide 的上下文:

    Glide.with(context)
    

    我希望这会有所帮助,如果您需要更多说明,请在 cmets 中告诉我!

    【讨论】:

    • 我已经添加了我的所有适配器类和错误。你能检查一下适配器类吗?谢谢你,很抱歉打扰。
    • 你可以调试和复制网址并将其粘贴到浏览器中。看到图片了吗?
    • 我刚刚意识到它给了我Intent { dat=content://com.android.providers.downloads.documents/document/msf:25 flg=0x1 } 作为回复,它是uri。但是当我将它转换为字符串时,它变成了content://com.android.providers.downloads.documents/document/msf%3A25。不过,我已经在adapter下解析回Uri了。
    • 但是将 uri 粘贴到浏览器并没有给我任何东西。说找不到你的文件。我已经粘贴了这个:content://com.android.providers.downloads.documents/document/msf:25
    • 请注意,除了回答之外,Glide.with(context).load(new File(uri.getPath())).into(holder.productImage); 行替换为Glide.with(context).load(Uri.parse(product.getImageUri)).into(holder.productImage);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多