png 加载内存不足 android

the png loading get out of memory android

我有一个带有网格的片段 view.I 我将 70 张图像放入网格 view.but 当我 运行 它从 memory.how 中取出的应用程序时 o 解决它?我应该将所有图像转换为位图吗? 这是我的片段 class:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View rootView = inflater.inflate(R.layout.fragment_games, container, false);

    mDrawerList = (GridView) rootView.findViewById(R.id.list_slidermenu);

    icons=new int[50];
    for(int i=1 ;i<icons.length ;i++)
    {
        icon_id="@drawable/data_" + i;
        icons[i]=getResources().getIdentifier(icon_id, null, MainActivity.PACKAGE_NAME);
        Log.e("log",""+icons[i]);
    }
    navDrawerItems = new ArrayList<NavDrawerItem>();
    for(int i=0 ;i<icons.length ;i++)
    {
        navDrawerItems.add(new NavDrawerItem(icons[i]));
    }
    adapter = new NavDrawerListAdapter(getActivity(),
            navDrawerItems);
    mDrawerList.setAdapter(adapter);

    return rootView;
}

这是我的适配器class:

public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            LayoutInflater mInflater = (LayoutInflater)
                    context.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
            convertView = mInflater.inflate(R.layout.itemlist, null);
        }
        ImageView imgIcon = (ImageView) convertView.findViewById(R.id.icon);

        imgIcon.setImageResource(navDrawerItems.get(position).getIcon());

        // displaying count
        // check whether it set visible or not
        return convertView;
    }

由于 Android 严格只允许您从 SDK 分配特定数量的内存,因此您必须使用较低质量的图片或不那么多的图片(70 是一个高值)。将它们加载到位图中会增加您对内存的需求或至少保持不变。如果你当时真的想加载70张那么大的图片,你必须考虑使用NDK(但这并不容易,我认为这里的工作量太大)。

这里你必须考虑几个事实。

  1. 如果70张图片给你一个OOM异常,那意味着你的图片必须更大。但大多数时候,您不需要图像原样。您的图像是 1024 * 1024 像素,但您在 100 * 100 比例图像视图中显示它。在这种情况下,您必须找到所需的大小并缩小图像,以免浪费堆并且图像不会像素化。 read here

  2. 您必须使用某种加载技术,例如渐进式加载,而不是一次将所有 70 个加载到网格中。然后只有用户滚动网格时才会加载图像。不会浪费内存。

  3. 您已取消分配给定特定时刻当前未显示在网格上的所有图像。

  4. 你必须为应用程序设置大堆,虽然不推荐但必须在这类应用程序中使用。

我不明白当位图的总和为 1MB 时内存怎么会用完。 但是当位图需要更多内存时,有一种简单的方法可以克服垃圾收集器. (我昨天找到了这个解决方案)。将每个 Bitmap 转换为您从 SDK 分配的 ByteBuffer。此 ByteBuffer 不计入您应用程序的内存。代码可能如下所示:


ByteBuffer mByteBuffer= ByteBuffer.allocateDirect(w*h*2); //w和h代表你的位图的宽度和高度(格式:RGB_565)

mByteBuffer.order(ByteBuffer.nativeOrder);

mBitmap.copyPixelsToBuffer(mByteBuffer); //现在你的Bitmap存储在一个Java外的Buffer中,我们就可以回收Bitmap了。当你想显示这个 ByteBuffer 时,你可以写

mByteBuffer.position(0);

mOtherBitmap.copyPixelsFromBuffer(mByteBuffer) 并且您的位图已准备就绪。在我的情况下它真的很快(~5 毫秒)

但我只在你的图片总和大于1MB时才推荐这个方法