如何解决asynctask中的内存不足错误

时间:2014-08-17 15:22:14

标签: android android-asynctask

我使用asynctask在listview中插入SD卡的图像。在229左右,图像logcat显示OUT OF MEMORY错误。我使用MediaStore.Images将SD卡中的图像检索到光标中。以下是我的代码:

CursorLoader cursorLoader = new CursorLoader(MainActivity.this,
            sourceUri, null, null, null, MediaStore.Images.Media.TITLE);
    Cursor cursor = cursorLoader.loadInBackground();
    new MyTask().execute(cursor);

MyTask扩展了AsyncTask。在这里,我使用do-while使用光标检索图像,并使用for循环通过使用ExifInterface来校正每个图像的方向:

class MyTask extends AsyncTask<Cursor, Bitmap, Void> {

    MyAdapter adap;
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        adap = (MyAdapter) listviewPic.getAdapter();
    }



    @Override
    protected Void doInBackground(Cursor... cursor) {
        // TODO Auto-generated method stub

        ThumbImage = new Bitmap[cursor[0].getCount()];
        cursor[0].moveToFirst();
        int count = 0;
        do {
            String _id = cursor[0].getString(cursor[0]
                    .getColumnIndex(MediaStore.Images.Media._ID));
            fileURI = Uri.withAppendedPath(sourceUri, _id);
            fileURI = Uri.parse("file://"
                    + getRealPathFromUri(getApplicationContext(), fileURI));

            file = new File(fileURI.getPath());
            Log.d("Fahad", "Value of pathURi is = " + fileURI);

            try {
                ThumbImage[count] = ThumbnailUtils.extractThumbnail(
                        BitmapFactory.decodeFile(file.getAbsolutePath()), 100,
                        100);
            } catch (OutOfMemoryError e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                Log.d("Fahad", "Error at = " + cursor[0].getPosition());
            }

            ++count;
        } while (cursor[0].moveToNext());
        for (int i = 0; i < ThumbImage.length; i++) {

            try {
                ExifInterface exif = new ExifInterface(file.getName());
                int orientation = exif.getAttributeInt(
                        ExifInterface.TAG_ORIENTATION, 1);
                if (orientation == exif.ORIENTATION_ROTATE_90) {
                    Matrix matrix = new Matrix();
                    matrix.postRotate(90);
                    Log.d("Fahad", "Changing orientation. ThumbImage id " + i);
                    ThumbImage[i] = Bitmap.createBitmap(ThumbImage[i], 0, 0,
                            ThumbImage[i].getWidth(),
                            ThumbImage[i].getHeight(), matrix, true);

                }

            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        publishProgress(ThumbImage);
        return null;

    }

    @Override
    protected void onProgressUpdate(Bitmap... bmp) {
        // TODO Auto-generated method stub
        MyAdapter adapter = new MyAdapter(getApplicationContext(),
                R.layout.row, null, bmp);
        listviewPic.setAdapter(adapter);
    }

    @Override
    protected void onPostExecute(Void result) {
        // TODO Auto-generated method stub
        super.onPostExecute(result);
    }

}

我已经制作了自定义适配器来显示图像:

class MyAdapter extends ArrayAdapter<String> {

    Bitmap[] bmp = null;
    Context context;

    public MyAdapter(Context context, int resource, List<String> objects,
            Bitmap[] bmp) {
        super(context, resource, objects);
        // TODO Auto-generated constructor stub
        this.bmp = bmp;
        this.context = context;
    }

    class MyViewHolder {
        ImageView imageView;

        public MyViewHolder(View v) { // TODO Auto-generated constructor
            // stub
            imageView = (ImageView) v.findViewById(R.id.imageView_row);
        }
    }

    @Override
    public int getCount() { // TODO Auto-generated method stub
        return bmp.length;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        Log.d("Fahad", "Inside getView");
        View row = convertView;
        MyViewHolder holder = null;
        if (row == null) {
            LayoutInflater layout = (LayoutInflater) context
                    .getSystemService(LAYOUT_INFLATER_SERVICE);
            row = layout.inflate(R.layout.row, parent, false);
            holder = new MyViewHolder(row);
            row.setTag(holder);
        } else {
            holder = (MyViewHolder) row.getTag();
        }
        holder.imageView.setBackground(new BitmapDrawable(getResources(),
                bmp[position]));
        return row;
    }
}

1 个答案:

答案 0 :(得分:0)

当您一次解码所有位图时,将发生OOM。

getView中加载位图是个好主意 (并且您可以使用具有异步和缓存系统的加载程序,如Piccaso