0

内部に CardViews を含む Recycle View で作成された製品リストがあります。各 CardView には製品の画像があります。

問題は、私が取得していることです

「java.lang.OutOfMemoryError」

. RecycleView Adapter で Picasso を使用しているためだと思います。

コードは次のとおりです。

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: メイン プロセス: uk.co.lexel.dimble、PID: 5503 java.lang.OutOfMemoryError: dalvik.system.VMRuntime.newNonMovableArray で OOM になるまで、4269112 の空きバイトと 4MB で 11760012 バイトの割り当てを割り当てることができませんでした(ネイティブメソッド) android.graphics.BitmapFactory.nativeDecodeAsset (ネイティブメソッド) android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:609) android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:444) android.graphics .drawable.Drawable.createFromResourceStream(Drawable.java:1080) で android.content.res.Resources.loadDrawableForCookie(Resources.java:2635) で android.content.res.Resources.loadDrawable(Resources.java:2540) で android.content.res.Resources.getDrawable(Resources.java:806) で android.content.Context.getDrawable(Context.java:458) で android.support.v4.content.ContextCompatApi21.getDrawable(ContextCompatApi21) .java:30) で android.support.v4.content.ContextCompat.getDrawable(ContextCompat.java:372) で android.support.v7.widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:202) で android.support.v7. widget.AppCompatDrawableManager.getDrawable(AppCompatDrawableManager.java:190) で android.support.v7.content.res.AppCompatResources.getDrawable(AppCompatResources.java:100) で android.support.v7.widget.AppCompatImageHelper.loadFromAttributes(AppCompatImageHelper.java:54) android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:66) で android.support.v7.widget.AppCompatImageView.(AppCompatImageView.java:56) で android.support.v7.app.AppCompatViewInflater.createView (AppCompatViewInflater.java:106) で android.support.v7.app.AppCompatDelegateImplV9.createView(AppCompatDelegateImplV9.java:1021) で android.support.v7.app.AppCompatDelegateImplV9.onCreateView(AppCompatDelegateImplV9.java:1080) で android.support. android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704) で android.view.LayoutInflater.rInflate(LayoutInflater.java:835) で android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) で android.view.LayoutInflater.rInflate(LayoutInflater.java:838) で android. android.view.LayoutInflater.rInflate(LayoutInflater.java:838) の view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:798) (LayoutInflater.java:515) android.view.LayoutInflater.inflate(LayoutInflater.java:423) で uk.co.something.controllers.activities.ProductListAdapter.onCreateViewHolder(ProductListAdapter.java:35) uk.co.something.controllers.activities.ProductListAdapter.onCreateViewHolder(ProductListAdapter.java:22) で android.support.v7.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:6290) で android.support.v7 .widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:5478) で android.support.v7.widget.GapWorker.prefetchPositionWithDeadline(GapWorker.java:270) で android.support.v7.widget.GapWorker.flushTaskWithDeadline(GapWorker.java) :324) android.support.v7.widget.GapWorker.flushTasksWithDeadline(GapWorker.java:337) で android.support.v7.widget.GapWorker.prefetch(GapWorker.java:344) で android.support.v7.widget. GapWorker.run(GapWorker.java:370) android.os.Handler.handleCallback(Handler.java:739) で android.os.Handler.dispatchMessage(Handler.java:95) で android.os.Looper.loop(Looper.java:148) で 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)5417) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) の java.lang.reflect.Method.invoke(ネイティブ メソッド) com.android.internal.os.ZygoteInit.main( ZygoteInit.java:616)5417) com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) の java.lang.reflect.Method.invoke(ネイティブ メソッド) com.android.internal.os.ZygoteInit.main( ZygoteInit.java:616)

ログには、問題がここにあると書かれています:

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

誰かが私を助けることができますか?

4

3 に答える 3

1

java.lang.OutOfMemoryErrorアプリが提供されている合計メモリを超えているため、エラーが発生しています。

アプリでは、これは、recyclerView に表示している画像のサイズが大きく、表示される前に画像ビューのサイズにスケーリングされていないことが原因である可能性があります

Picasso を使用して画像を適切にスケーリングするには、Picasso の .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

于 2016-12-22T11:45:13.430 に答える
0

私のプロジェクトでは、ほぼすべてのライブラリを使用して recylerview に画像をロードしましたが、すべてのライブラリに問題があります。しかし、recyclerview で画像を読み込む場合は、Universal Image Loader が最適です。

于 2016-12-22T12:46:38.240 に答える
0

java.lang.OutOfMemoryError を簡単に防止するには、スムーズなスクロールで Glide Image Loader を使用します。以下のリンクを使用 Glide Tutorial

于 2016-12-22T12:04:29.227 に答える