首页 > 解决方案 > Android:如何重用或限制位图的数量

问题描述

我确实有一个应用程序可以显示来自 firebase-Realtime 的图像和其他一些文本信息,我的应用程序内存使用存在问题,它可以轻松跨越 400+mb 所以我使用分析器检查并解决了我的应用程序的每个 MemoryLeaks,现在,当我检查 Android Studio 分析器时,我发现有大量位图正在使用大量内存。

另外,我正在使用 Picasso 从适配器内将图像加载到 Recycleview

有时也使用 Glide

所以我想知道是否可以解决这些位图内存使用问题,或者是否可以限制可以使用的位图数量,因为每次显示新图像时,应用程序都会制作一个新位图并使用更多 RAM。

将图像加载到 recyclerview 的适配器代码:

public class HomeScreenWorkViewHolder  extends RecyclerView.ViewHolder {

    View view;
    DatabaseReference likeReference;
    public ImageView like_btn;
    public TextView like_text;
    public HomeScreenWorkViewHolder(@NonNull View itemView) {
        super(itemView);

        like_btn = itemView.findViewById(R.id.like_btn);
        like_text = itemView.findViewById(R.id.like_text);
        view = itemView;
    }
    public HomeScreenWorkViewHolder(@NonNull View itemView, OnItemClick callBack) {
        super(itemView);

        like_btn = itemView.findViewById(R.id.like_btn);
        like_text = itemView.findViewById(R.id.like_text);

        view = itemView;

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                callBack.onItemClicked(getAdapterPosition());
            }
        });
    }
    public void setdetails( String name, String image, String description, String location) {
        TextView mtitletv = view.findViewById(R.id.product_layout_name);
        TextView mdesrcriptiontv = view.findViewById(R.id.product_layout_description);
        TextView mlocationtv = view.findViewById(R.id.product_layout_location);
        ImageView mImagetv = view.findViewById(R.id.product_layout_image);


        mtitletv.setText(name);
        mdesrcriptiontv.setText(description);
        mlocationtv.setText(location);
        Picasso.get().load(image).placeholder(R.drawable.ic_baseline_cloud_download_24).into(mImagetv);
    }

剖析器 在此处输入图像描述

在此处输入图像描述

标签: androidandroid-studioandroid-recyclerviewbitmap

解决方案


听起来您要么保留对位图的引用。如果不是这种情况,但您试图将引用保留在内存中,但通过更改样本大小来减少内存占用。

采样大小可以这样认为:如果你有一个 1000x1000 的图像,每像素 8 位。你有一个 1,000,000 字节的图像加载到内存中。假设您只需要 100x100 的缩略图。然后,您可以将采样大小更改为 10,它会从文件中每隔 10 个像素读取一次,从而构建一个更新/更小的内存占用图像。这将从 1,000,000 字节变为 10,000 字节。

试试这个 SO question 的答案..

将图像加载到位图对象时出现奇怪的 OutOfMemory 问题

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeStream(is, null, options);

推荐阅读