0

我有一个产品列表,里面有一个带有CardViews的回收视图。每个CardView都有该产品的图像。如何在RecycleView中正确使用Picasso库

的问题是,我得到一个

"java.lang.OutOfMemoryError"

。 我认为是因为我在我的RecycleView适配器中使用了毕加索。

下面是代码:

import android.content.Context; 
import android.support.v7.widget.RecyclerView; 
import android.view.LayoutInflater; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.ImageView; 
import android.widget.TextView; 

import com.squareup.picasso.Picasso; 

import java.util.List; 

import uk.co.something.R; 
import uk.co.something.Product; 


public class ProductListAdapter extends RecyclerView.Adapter<ProductListAdapter.ViewHolder> { 
    private List<Product> products; 
    private int rowLayout; 
    private Context appContext; 

    public ProductListAdapter(List<Product> products, int rowLayout, Context appContext) { 
     this.products = products; 
     this.rowLayout = rowLayout; 
     this.appContext = appContext; 
    } 

    @Override 
    public ProductListAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) { 
     View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false); 
     return new ProductListAdapter.ViewHolder(v); 
    } 

    @Override 
    public void onBindViewHolder(ProductListAdapter.ViewHolder viewHolder, int i) { 
     Product product = products.get(i); 
     Picasso.with(appContext).load(product.getUrl().getImage()).into(viewHolder.image); 
     Picasso.with(appContext).load(product.getRetailer().getIcon()).into(viewHolder.logo); 
     String productPrice = (product.getPrice().getDiscounted() == null || Double.parseDouble(product.getPrice().getDiscounted()) <= 0) ? product.getPrice().getCost() : product.getPrice().getDiscounted(); 
     viewHolder.price.setText("\u00a3" + productPrice); 

    } 

    @Override 
    public int getItemCount() { 
     return products == null ? 0 : products.size(); 
    } 

    static class ViewHolder extends RecyclerView.ViewHolder { 
     public ImageView image; 
     public ImageView logo; 
     public TextView price; 

     ViewHolder(View itemView) { 
      super(itemView); 
      image = (ImageView) itemView.findViewById(R.id.product_list_cardview_image); 
      logo = (ImageView) itemView.findViewById(R.id.product_list_cardview_logo); 
      price = (TextView) itemView.findViewById(R.id.product_list_cardview_price); 
     } 

    } 
} 

我得到的错误是这个:

E/AndroidRuntime: FATAL EXCEPTION: main Process: uk.co.lexel.dimble, PID: 5503 java.lang.OutOfMemoryError: Failed to allocate a 11760012 byte allocation with 4269112 free bytes and 4MB until OOM at dalvik.system.VMRuntime.newNonMovableArray(Native Method) at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609) at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444) at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:1080) at android.content.res.Resources.loadDrawableForCookie(Resources.java:2635) at android.content.res.Resources.loadDrawable(Resources.java:2540) at android.content.res.Resources.getDrawable(Resources.java:806) at android.content.Context.getDrawable(Context.java:458) at android.support.v4.content.ContextCompatApi21.getDrawable(ContextCompatApi21.java:30) at android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:372) at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:202) at android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:190) at android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100) at android.support.v7.widget.AppCompatImageHelper.loadFromAttributes(AppCompatImageHelper.java:54) at android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:66) at android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:56) at android.support.v7.app.AppCompatViewInflater.createView(AppCompatViewInflater.java:106) at android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1021) at android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1080) at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:47) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:746) at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) at android.view.LayoutInflater.rInflate(LayoutInflater.java:835) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) at android.view.LayoutInflater.rInflate(LayoutInflater.java:838) at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) at android.view.LayoutInflater.inflate(LayoutInflater.java:515) at android.view.LayoutInflater.inflate(LayoutInflater.java:423) at uk.co.something.controllers.activities.ProductListAdapter.onCreateViewHolder(ProductListAdapter.java:35) at uk.co.something.controllers.activities.ProductListAdapter.onCreateViewHolder(ProductListAdapter.java:22) at android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6290) at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5478) at android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:270) at android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java:324) at android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:337) at android.support.v7.widget.GapWorker.prefetch(GapWorker.java:344) at android.support.v7.widget.GapWorker.run(GapWorker.java:370) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

在日志中说,问题就在这里:

View v = LayoutInflater.from(viewGroup.getContext()).inflate(rowLayout, viewGroup, false); 

有人能帮我吗?

+0

我认为你在布局xml中有一些大的图像。请展示它。 –

回答

1

你得到java.lang.OutOfMemoryError错误,因为你的应用超过了提供给它的总内存。

在你的应用程序,这可能是因为你在你的recyclerView显示图像的尺寸大,显示

对于正常缩放你的图片才他们没有缩放到ImageView的大小使用毕加索你可以使用.fit()方法在毕加索

Picasso 
.with(context) 
.load(UsageExampleListViewAdapter.eatFoodyImages[0]) 
.fit() 
// call .centerInside() or .centerCrop() to avoid a stretched image 
.into(imageViewFit); 

或替代毕加索,你可以用滑翔

compile 'com.github.bumptech.glide:glide:3.7.0' 

Glide.with(context) 
    .load(image) 
    .asBitmap()‌​.transform(new CenterCrop(context)) 
    .diskCacheStrategy(DiskCacheStrategy.NONE) 
    .skipMemoryCache(true) 
    .int‌​o(your_imageview) 

您可以通过启用大型堆在你的清单

android:largeHeap="true" 

更多关于图片缩放和负荷也会增加分配给您的应用程序的默认内存您可以点击链接查看图片:https://developer.android.com/training/displaying-bitmaps/load-bitmap.html

-1

请将您的Recyclerview行设计代码,可能会因为图像大小而出现问题。

+0

这不是一个答案。你不应该留下评论作为答案。 –

0

防止java.lang.OutOfMemoryError简单的使用滑翔图像的平滑scrolling.Use装载机以下链接 Glide Tutorial

0

在项目中,我使用几乎所有的图书馆recylerview载入图像,但所有的图书馆有一些问题。但通用图像加载程序是在回收站视图中加载图像时最好的。