【问题标题】:Throwing OutOfMemoryError "Failed to allocate a 28 byte allocation with 4000 free bytes and 3KB until OOM"抛出 OutOfMemoryError “无法分配 28 字节分配,其中 4000 个空闲字节和 3KB 直到 OOM”
【发布时间】:2018-08-27 18:16:13
【问题描述】:

应用崩溃时出现的错误

08-27 23:32:33.714 1178-1223/com.statusstock.wallpaperhd I/art: Clamp target GC heap from 398MB to 384MB
08-27 23:32:33.715 1178-1223/com.statusstock.wallpaperhd I/art: Alloc concurrent mark sweep GC freed 9(288B) AllocSpace objects, 0(0B) LOS objects, 0% free, 382MB/384MB, paused 533us total 58.639ms
    Forcing collection of SoftReferences for 3MB allocation
    Starting a blocking GC Alloc
08-27 23:32:33.766 1178-1223/com.statusstock.wallpaperhd I/art: Clamp target GC heap from 398MB to 384MB
    Alloc concurrent mark sweep GC freed 3(96B) AllocSpace objects, 0(0B) LOS objects, 0% free, 382MB/384MB, paused 439us total 51.432ms
08-27 23:32:33.766 1178-1223/com.statusstock.wallpaperhd W/art: Throwing OutOfMemoryError "Failed to allocate a 3686412 byte allocation with 1976816 free bytes and 1930KB until OOM"
08-27 23:32:33.766 1178-1223/com.statusstock.wallpaperhd D/skia: --- decoder->decode returned false

这是一个壁纸应用程序,它在 Picasso 的帮助下通过从 firebase 检索图像 URL 以网格视图显示图像。如果您单击图像,它将在 Picasso 和 firebase 的帮助下在新活动中打开。但是当我运行我的应用程序时,它会占用太多内存,并且在使用几分钟后应用程序崩溃。我使用过 android:hardwareAccelerated="false" 和 android:largeHeap="true" 但这些都不起作用。

代码:

Viewholder.java

import ...

public class ViewHolder extends RecyclerView.ViewHolder {

    View mView;

    public ViewHolder(final View itemView) {
        super(itemView);

        mView = itemView;

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mClickListener.onItemClick(v, getAdapterPosition());
            }
        });

        itemView.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {

                mClickListener.onItemLongClick(v, getAdapterPosition());
                return true;
            }
        });

    }


    public void setDetails(Context ctx, String image){


        ImageView mImageTv = mView.findViewById(R.id.rImageView);

        Picasso.get().load(image).into(mImageTv);

    }


    private ViewHolder.ClickListener mClickListener;

    public interface ClickListener{

        void onItemClick(View view, int position);
        void onItemLongClick(View view, int position);

    }

    public void setOnclickListener(ViewHolder.ClickListener clickListener){

        mClickListener = clickListener;

    }


}

在网格视图中显示壁纸的片段

public class HDFragment extends Fragment {

    RecyclerView mRecyclerView;
    FirebaseDatabase mFirebaseDatabase;
    DatabaseReference mRef;


    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_hd, container, false);


        mRecyclerView = view.findViewById(R.id.recyclerView_hd);
        mRecyclerView.setHasFixedSize(true);


        mRecyclerView.setLayoutManager(new GridLayoutManager(getActivity(), 3));


        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mRef = mFirebaseDatabase.getReference("New");

        FirebaseRecyclerAdapter<Model, ViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Model, ViewHolder>(Model.class, R.layout.row, ViewHolder.class, mRef) {
            @Override
            protected void populateViewHolder(ViewHolder viewHolder, Model model, int position) {

                viewHolder.setDetails(getActivity().getApplicationContext(), model.getImage());

            }

            @Override
            public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {


                ViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);
                viewHolder.setOnclickListener(new ViewHolder.ClickListener() {
                    @Override
                    public void onItemClick(View view, int position) {

                        String mImage = getItem(position).getImage();


                        Intent intent = new Intent(view.getContext(), PostDetailsActivity2.class);

                        intent.putExtra("image", mImage);
                        startActivity(intent);


                    }

                    @Override
                    public void onItemLongClick(View view, int position) {


                    }
                });


                return viewHolder;
            }
        };


        mRecyclerView.setAdapter(firebaseRecyclerAdapter);


        return view;
    }
}

FullImage Activity 在单击时全屏显示图像

mImageTv = findViewById(R.id.full_imageView1);

        String image = getIntent().getStringExtra("image");


        Picasso.get().load(image).fit().centerCrop().memoryPolicy(MemoryPolicy.NO_CACHE).into(mImageTv);

请帮忙..谢谢

【问题讨论】:

    标签: android performance android-fragments memory-leaks out-of-memory


    【解决方案1】:

    如果你真的需要更多内存,你可以在 Manifest 中为应用程序设置这个属性来解决问题(也许):

    android:largeHeap="true"
    

    虽然它不是免费的,你可以在这篇文章中看到: What are advantages of setting largeHeap to true?

    【讨论】:

    • 我还添加了 android:hardwareAccelerated="false"
    • 你知道这里的问题是图像。如果android:largeHeap="true" 没有帮助,您将不得不重新设计它们。
    • 我认为清除缓存可以解决这个问题...请你帮我解决这个问题
    • 什么意思?您应用的缓存?
    【解决方案2】:

    您正在尝试加载大图像、降低图像分辨率或使用处理大图像的视图,例如this

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-03
      • 1970-01-01
      • 2015-11-21
      • 2017-12-07
      • 1970-01-01
      相关资源
      最近更新 更多