繁体   English   中英

处理带有RecyclerView和Picasso问题的大量图像

[英]Handle large list of images with RecyclerView and Picasso issues

更新资料
我确定了我的问题。 我正在尝试使用RecyclerView处理大量图像列表(.webp格式的770张图像,图像总大小为10mb),并且显示内存不足错误。
如何解决这个问题呢?
我正在使用毕加索加载图像


抛出OutOfMemoryError“未能分配带有107504个空闲字节和104KB的810076字节分配,直到OOM”


如果列表大小小于100,如何使用回收站视图加载700个项目,则没有问题。 每个项目都包含webp共振峰中的图像
我正在尝试此代码,它抛出了内存不足错误并导致应用程序崩溃。 如何解决这个错误?
(它包含700个iamges,全部为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) { }
                }

热带鱼手册上的android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:805)上的android.graphics.BitmapFactory.nativeDecodeAsset(本机方法)处的java.lang.OutOfMemoryError。网址为tropicalfishhandbook的midhilaj.com.v2.aaa(未知来源)。android.support.v7的android.support.v7.widget.RecyclerView $ Adapter.onBindViewHolder(未知来源)的midhilaj.com.v2.aaonBindViewHolder(未知来源)。 android.support.v7.widget.RecyclerView $ Recycler.tryBindViewHolderByDeadline(未知源)的widget.RecyclerView $ Adapter.bindViewHolder(未知源) android.support.v7.widget.RecyclerView $ Recycler.getViewForPosition(未知源)上的support.v7.widget.RecyclerView $ Recycler.getViewForPosition(未知源)android.support.v7.widget.LinearLayoutManager $ LayoutState.next(未知源)。 android.support.v7.widget.LinearLayoutManager.fill(未知来源)上的support.v7.widget.GridLayoutManager.layoutChunk(未知源)android.support上的android.support.v7.widget.LinearLayoutManager.onLayoutChildren(未知源) v7.widget.GridLayoutManager.onLayoutChildren(未知源)在android.support.v7.widget.RecyclerView.dispatchLayoutStep2(未知源)在android.support.v7.widget.RecyclerView.onMeasure(android.view.View处) android.widget.RelativeLayout.measureChildHorizo​​ntal(RelativeLayout.java:719)处Measure(View.java:16749)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) .widget.LinearLayout.onMeasure(LinearLayout.java:589)在android.view.View.measure(Vie w.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 android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5295)上的.measure(View.java:16749)android.support.design.widget.CoordinatorLayout.a(未知源)android.support.design.widget.ha (未知来源)在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.measureChildWithMa android.widget.FrameLayout.onMeasure上的rgins(ViewGroup.java:5295)(android.support.v7.widget.ContentFrameLayout.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(LinearLayout.java:696) android.widget.FrameLayout上的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的智能手机中正常工作,在500mbb的智能手机中崩溃,并且在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()+"");
                   }

添加依赖

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

资源加载

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

实现RecyclerView适配器。

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然后您的显示逻辑将在那里,并根据位置加载项目。

删除毕加索并使用Glide

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

                                .into(holder.image);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM