我使用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;
}
}