簡體   English   中英

Android:如何在活動中加載多張圖片和聲音而不會出現內存不足錯誤

[英]Android: How to load multiple pictures and sounds in an activity without a out of memory error

因此,我有一個活動是縮小為約64x64像素框的高清圖像的gridview。 我希望能夠獲取圖像,然后將其加載到活動中,但是我收到一個錯誤,指出加載所有圖片所需的內存比模擬器/電話可以處理的要高得多。

我通過進入Photoshop並制作64x64圖像來解決了這個問題,但是我已經看到了運行視頻並在當前活動視圖中具有數百張圖像的應用程序。 他們如何在一個列表視圖中使用所有內存進行編譯?

我有另一個應用程序,它是一個動畫,可以播放20張圖片的全屏動畫-但在Android Studio中它具有相同的內存綁定錯誤。

如何在一個活動中加載20張圖片而不會出現內存不足錯誤。

GridView @Override受保護的活動代碼 void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState); setContentView(R.layout.wallpapers);

    //**
    //Gridview, onclick of icon will open up dialog
    //allows to SAVE, SET, CANCEL - not in that order

    GridView gridview = (GridView) findViewById(R.id.gridview);
    gridview.setAdapter(new ImageAdapter(this));

    gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v,
                                int position, long id) {
            Toast.makeText(Wallpaper.this, "Setting BG to ..." + position,
                    Toast.LENGTH_SHORT).show();
        }
    });
}

ImageAdapter的代碼

public class ImageAdapter extends BaseAdapter {
private Context mContext;

public ImageAdapter(Context c) {
    mContext = c;
}

public int getCount() {
    return mThumbIds.length;
}

public Object getItem(int position) {
    return null;
}

public long getItemId(int position) {
    return 0;
}

// create a new ImageView for each item referenced by the Adapter
public View getView(int position, View convertView, ViewGroup parent) {
    ImageView imageView;
    if (convertView == null) {
        // if it's not recycled, initialize some attributes
        imageView = new ImageView(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(85, 85));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(8, 8, 8, 8);
    } else {
        imageView = (ImageView) convertView;
    }

    imageView.setImageResource(mThumbIds[position]);
    return imageView;
}

// references to our images
private Integer[] mThumbIds = {
        R.raw.es_1_pix,  R.raw.es1_c, R.raw.es2_c, R.raw.es_1_pix
            //.raw.es_1_pix,R.raw.es_1_pix,R.raw.es_1_pix,R.raw.es_1_pix,R.raw.es_1_pix
        //R.raw.es2_c, R.raw.es3_c, R.raw.es4_c,
        //R.raw.es5_c, R.raw.es6_c, R.raw.es7_c
};
}

不確定聲音,但我知道圖像需要使用inJustDecodeBounds=true的Sample大小。

public int calculateInSampleSize(BitmapFactory.Options options) {

        DisplayMetrics displayMetrics = cxt.getResources().getDisplayMetrics();
        int reqWidth = displayMetrics.widthPixels;

        final int height = options.outHeight;
        final int width = options.outWidth;

        double devCal2 =  (height*1000)/width;
        int reqHeight = (int) ((devCal2/1000)*reqWidth);

        int inSampleSize = 1;

        if (height > reqHeight || width > reqWidth) {

            final int halfHeight = height / 2;
            final int halfWidth = width / 2;

            // Calculate the largest inSampleSize value that is a power of 2 and keeps both
            // height and width larger than the requested height and width.
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }

        return inSampleSize;
    }

    public Bitmap createBitmap(){

        BitmapFactory.Options options2 = new BitmapFactory.Options();
        options2.inJustDecodeBounds = true;
        options2.inDither=true;
        BitmapFactory.decodeFile(cxt.getExternalFilesDir(filepath) +"/companylogo.png",options2);
        options2.inSampleSize = calculateInSampleSize(options2);//=32
        options2.inJustDecodeBounds = false;

        return BitmapFactory.decodeFile(cxt.getExternalFilesDir(filepath) +"/companylogo.png",options2);
    }

作為參考,請檢查http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

有幾件事要考慮。

  1. 更簡單的解決方案-使用圖像管理庫,其中有很多。 他們所有人都做以下事情:

在所有位置(而不是位圖)使用WeakReference<Bitmap> WeakReference意味着沒有足夠的內存時,系統可以從內存中清除圖像。

如果要顯示20 64 * 64圖像,請確保未在內存中存儲20 1024 * 1024圖像,請在運行時或應用程序外部將其大小調整為64 * 64。

一般來說,Android可以輕松處理20個平均大小的圖像(顯然不是很大的圖像)。 如果出錯,則說明代碼有問題。

發布代碼后進行UPDATE:資源文件中包含的圖像非常大,將其縮小后應該沒問題。

如果您確實需要完整的HD圖像,則可以計算所需的空間,然后將它們一個個地替換為一個占位符圖像,然后將其加載到視圖中。 然后,在加載一張圖像后,請確保系統從內存中清除了該圖像。 但是就像大多數人所說的,如果它僅從20張圖像中崩潰,那可能是另外一回事了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM