【问题标题】:Handle large list of images with RecyclerView and Picasso issues使用 RecyclerView 和 Picasso 问题处理大量图像
【发布时间】:2019-01-20 21:30:27
【问题描述】:

更新
我发现了我的问题。我正在尝试使用 RecyclerView 处理大量图像(.webp 格式的 770 个图像,图像总大小为 10mb),它显示内存不足错误。
如何解决这个问题?
我正在使用毕加索来加载图像


抛出 OutOfMemoryError “无法分配 810076 字节分配,其中 107504 空闲字节和 104KB 直到 OOM”


如果列表大小小于 100 没有问题,如何使用回收站视图加载 700 项。每个项目都包含 webp 共振峰的图像
我正在尝试这段代码,它抛出内存不足错误并使应用程序崩溃。如何解决这个错误?
(它包含 700 张图片,全部采用 webp 格式,并且此代码在 recyclerview 中,带有网格布局)

 InputStream ins = null;

                try {
                    ins = mContext.getAssets().open(mData.get(position).getImagename()+".webp");
                    Bitmap bitmap = BitmapFactory.decodeStream(ins);
                    holder.image.setImageBitmap(bitmap);
                } catch (final IOException e) {
                    e.printStackTrace();
                } finally {
                    if (ins != null)
                        try {
                            ins.close();
                        } catch (IOException e) { }
                }

java.lang.OutOfMemoryError 在 android.graphics.BitmapFactory.nativeDecodeAsset(本机方法) 在 android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:805) 在 android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:845) 在tropicalfishhandbook.midhilaj.com.v2.a.a.a(未知来源) 在tropicalfishhandbook.midhilaj.com.v2.a.a.onBindViewHolder(未知 资源) 在 android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder(未知 资源) 在 android.support.v7.widget.RecyclerView$Adapter.bindViewHolder(未知 资源) 在 android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline(未知 资源) 在 android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(未知 资源) 在 android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(未知 资源) 在 android.support.v7.widget.RecyclerView$Recycler.getViewForPosition(未知 资源) 在 android.support.v7.widget.LinearLayoutManager$LayoutState.next(未知 资源) 在 android.support.v7.widget.GridLayoutManager.layoutChunk(未知 资源) 在 android.support.v7.widget.LinearLayoutManager.fill(未知来源) 在 android.support.v7.widget.LinearLayoutManager.onLayoutChildren(未知 资源) 在 android.support.v7.widget.GridLayoutManager.onLayoutChildren(未知 资源) 在 android.support.v7.widget.RecyclerView.dispatchLayoutStep2(未知 资源) 在 android.support.v7.widget.RecyclerView.onMeasure(未知来源) 在 android.view.View.measure(View.java:16749) 在 android.widget.RelativeLayout.measureChildHorizo​​ntal(RelativeLayout.java:719) 在 android.widget.RelativeLayout.onMeasure(RelativeLayout.java:455) 在 android.view.View.measure(View.java:16749) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295) 在 android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1413) 在 android.widget.LinearLayout.measureVertical(LinearLayout.java:696) 在 android.widget.LinearLayout.onMeasure(LinearLayout.java:589) 在 android.view.View.measure(View.java:16749) 在 android.widget.ScrollView.measureChildWithMargins(ScrollView.java:1235) 在 android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 在 android.widget.ScrollView.onMeasure(ScrollView.java:327) 在 android.view.View.measure(View.java:16749) 在 android.support.constraint.ConstraintLayout.a(未知来源) 在 android.support.constraint.ConstraintLayout.onMeasure(未知来源) 在 android.view.View.measure(View.java:16749) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295) 在 android.support.design.widget.CoordinatorLayout.a(未知来源) 在 android.support.design.widget.h.a(未知来源) 在 android.support.design.widget.AppBarLayout$ScrollingViewBehavior.a(未知 资源) 在 android.support.design.widget.CoordinatorLayout.onMeasure(未知 资源) 在 android.view.View.measure(View.java:16749) 在 android.support.v4.widget.DrawerLayout.onMeasure(未知来源) 在 android.view.View.measure(View.java:16749) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295) 在 android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 在 android.support.v7.widget.ContentFrameLayout.onMeasure(未知来源) 在 android.view.View.measure(View.java:16749) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295) 在 android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1413) 在 android.widget.LinearLayout.measureVertical(LinearLayout.java:696) 在 android.widget.LinearLayout.onMeasure(LinearLayout.java:589) 在 android.view.View.measure(View.java:16749) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295) 在 android.widget.FrameLayout.onMeasure(FrameLayout.java:310) 在 android.view.View.measure(View.java:16749) 在 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295) 在 android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1413) 在 android.widget.LinearLayout.measureVertical(Lin

我的清单文件

<application
        android:name=".App"
        android:allowBackup="false"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:largeHeap="true"
        android:supportsRtl="true"
        tools:replace="android:allowBackup"
        android:theme="@style/AppTheme">

更新 我换成了 Picasso,它在 2gb ram 的智能手机中工作,它在 500mb 的智能手机中崩溃,有时它也在 1gb ram 智能手机中崩溃
添加毕加索后,现在图像需要 5 秒才能加载

更新的新代码 但问题没有解决


这是我用来加载的代码

try {
                       List<Millafish_profile> list = mDatabaseManager.getAll();
                       for (int i = 0; i < list.size(); i++) {
                           final int finalI = i;//"@drawable/" +
                           String uri = list.get(i).getPic().replace("’", "_").replace(".jpg", "").replace(".png", "").replace("-", "_");  // where myresource (without the extension) is the file
                           // Log.i("uri_"+i,uri+"");
                           Millafish_profile millafish_profile = list.get(i);//mDatabaseManager.getprofile(mDatabaseManager.getallfishname().get(finalI));
                           millafish_profile.setImageuri(uri.toLowerCase());
                           millafish_profileList.add(millafish_profile);
                           //if(i==20)break;

                           {
                               //adapter.notifyItemChanged(i);
                               //(millafish_profileList.size());
                           }

                       }
                       adapter.notifyDataSetChanged();
                       millafish_profileList_org = new ArrayList<>();
                       millafish_profileList_org.addAll(millafish_profileList);

                   }catch (Exception e){
                       Log.e("homepage",e.getMessage()+"");
                   }

【问题讨论】:

  • 你试过压缩位图吗
  • 不,我不尝试压缩
  • 代码与问题共享
  • 所以尝试压缩看我的回答
  • 肯定会崩溃,并且由于图像太多会出现内存问题。最好使用 ListView 或者 RecyclerView 来一张一张的加载图片。通过使用这个,只有渲染的图像会加载到内存中,而不是一次加载所有的图像。

标签: java android android-recyclerview android-drawable picasso


【解决方案1】:

移除 Picasso 并使用 Glide

Glide.with(mContext).load(Uri.parse("file:///android_asset/"+mData.get(position).getImageuri()+".webp"))
                                .thumbnail(0.5f)

                                .into(holder.image);

【讨论】:

    【解决方案2】:

    添加依赖

    implementation 'com.squareup.picasso:picasso:2.71828'
    

    RESOURCE LOADING

    Picasso.get().load(R.drawable.landing_screen).into(imageView1);
    Picasso.get().load("file:///android_asset/DvpvklR.png").into(imageView2);
    Picasso.get().load(new File(...)).into(imageView3);
    

    你的情况

    final String imagePath = "file:///android_asset/" + mData.get(position).getImagename()+".webp";
    
    Picasso.get().load(imagePath).into(holder.image);
    

    更新

    Picasso.get()
    .load(imagePath)
    .centerCrop()
    .fit()
    // .resize(100, 100)  // Check if resize can help without fit/centerCrop
    .memoryPolicy(MemoryPolicy.NO_CACHE)
    .into(holder.image);
    

    更新 2

    Implement RecyclerView adapter.

    public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
          private final List<Millafish_profile> dataSet;
    
        // Provide a reference to the views for each data item
        // Complex data items may need more than one view per item, and
        // you provide access to all the views for a data item in a view holder
        public static class ViewHolder extends RecyclerView.ViewHolder {
            public ImageView image;
            public ViewHolder(View v) {
                super(v);
                image = v.findViewById(R.id.image_view);
            }
        }
    
      public MyAdapter(){
        this.dataSet = mDatabaseManager.getAll();
      }
      // Create new views (invoked by the layout manager)
        @Override
        public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                       int viewType) {
            // create a new view
            View myView = LayoutInflater.from(parent.getContext())
                    .inflate(R.layout.my_view_that_contains_imageview, parent, false);
            ...
            ViewHolder vh = new ViewHolder(myView);
            return vh;
        }
    
        // Replace the contents of a view (invoked by the layout manager)
        @Override
        public void onBindViewHolder(ViewHolder holder, int position) {
            // - get element from your dataset at this position
            // - replace the contents of the view with that element
            final String imagePath = "file:///android_asset/" + dataSet.get(position).getImagename()+".webp";
            Picasso.get().load(imagePath).into(holder.image);
        }
    
        // Return the size of your dataset (invoked by the layout manager)
        @Override
        public int getItemCount() {
            return dataSet.size();
        }
    
    • RecyclerView 将通过用户滚动处理加载更多图像。

    onBindViewHolder 在需要在屏幕上显示项目时调用,然后您的显示逻辑将在那里,只需根据位置加载项目即可。

    【讨论】:

    • 我换成了 picasso,它在 2gb 内存的手机上工作,在 500mb 的手机上不工作,在 1gb 内存的智能手机上崩溃了一段时间
    • 检查Picasso fit() or resize方法。
    • 它就像这样 Picasso.with(mContext).load(Uri.parse("file:///android_asset/"+mData.get(position).getImagename()+".webp" )).fit().into(holder.image);
    • 查看Github issue
    • 检查skipMemoryCache(),顺便说一句,最新版本使用的是Picasso.get()而不是Picasso.with(mContext)
    猜你喜欢
    • 1970-01-01
    • 2019-04-08
    • 1970-01-01
    • 1970-01-01
    • 2013-01-31
    • 1970-01-01
    • 2019-04-26
    • 2020-07-11
    • 1970-01-01
    相关资源
    最近更新 更多