OutOfMemoryError при установке Uri с помощью setImageURI
Пользователь выбирает изображение, путь к нему затем сохраняется в моей базе данных SQLite. Затем я заполняю текст / изображения из SQLite в GridView
используя CursorAdapter:
public class MyNiftyAdapter extends CursorAdapter{
private LayoutInflater mInflater;
private Cursor cur;
public MyNiftyAdapter(Context context, Cursor c) {
super(context,c);
this.mInflater = LayoutInflater.from(context);
this.cur = c;
}
public MyNiftyAdapter(Context context, Cursor c, boolean autoRequery)
{
super(context, c, autoRequery);
this.mInflater = LayoutInflater.from(context);
this.cur = c;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
if(convertView == null)
{
convertView = this.mInflater.inflate(R.layout.single_item, null);
viewHolder = new ViewHolder();
viewHolder.name = (TextView)convertView.findViewById(R.id.txtName);
viewHolder.Age = (TextView)convertView.findViewById(R.id.studentage);
viewHolder.Id = (TextView)convertView.findViewById(R.id.rowid);
viewHolder.Image = (CircularImageView)convertView.findViewById(R.id.imgFood);
convertView.setTag(viewHolder);
}else
{
viewHolder = (ViewHolder)convertView.getTag();
}
this.cur.moveToPosition(position);
viewHolder.name.setText(this.cur.getString(this.cur.getColumnIndex(SQLiteHelper.NAME)));
viewHolder.Age.setText(this.cur.getString(this.cur.getColumnIndex(SQLiteHelper.AGE)));
viewHolder.Id.setText(this.cur.getString(this.cur.getColumnIndex(SQLiteHelper._ID)));
Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
viewHolder.Image.setImageURI(jg);
return convertView;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Dont need to do anything here
return null;
}
static class ViewHolder
{
TextView name;
TextView Age;
TextView Id;
CircularImageView Image;
}
}
Когда я выбираю большие изображения, я получаю сообщение об ошибке:
java.lang.OutOfMemoryError: Failed to allocate a 21566748 byte allocation with 8448604 free bytes and 8MB until OOM
Я видел, что растровое изображение должно быть уменьшено, но я просто использую Uri
файла и его отображение. Есть ли способ избежать этой проблемы, поскольку я не хочу сохранять другой (сжатый) файл на устройстве?
я пытался android:hardwareAccelerated="false"
в манифесте.
Вот что сработало для меня:
В конечном итоге я использовал Picasso в ответах, но важно отметить, что при загрузке URI
от устройства, чтобы загрузить URI
как это:
Picasso.with(mContext)
.load(new File(String.valueOf(Uri)))
.placeholder(R.drawable.profile)
.resize(800, 800)
.centerCrop()
.into(viewHolder.Image);
обратите внимание, что я использовал .load(new File(String.valueOf(Uri)))
вместо .load(uri)
, Если вы загрузите URI
непосредственно представление вернется пустым.
Если вы загружаете изображение из URL, оно должно быть загружено так:
Picasso.with(mContext)
.load(URL)
.placeholder(R.drawable.profile)
.resize(800, 800)
.centerCrop()
.into(viewHolder.Image);
В итоге мой адаптер выглядел так:
public class MyNiftyAdapter extends CursorAdapter{
private LayoutInflater mInflater;
private Cursor cur;
private Context mContext;
public MyNiftyAdapter(Context context, Cursor c) {
super(context,c);
this.mInflater = LayoutInflater.from(context);
this.mContext = context;
this.cur = c;
}
public MyNiftyAdapter(Context context, Cursor c, boolean autoRequery)
{
super(context, c, autoRequery);
this.mInflater = LayoutInflater.from(context);
this.cur = c;
this.mContext = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
ViewHolder viewHolder;
if(convertView == null)
{
convertView = this.mInflater.inflate(R.layout.single_item, null);
viewHolder = new ViewHolder();
viewHolder.name = (TextView)convertView.findViewById(R.id.txtName);
viewHolder.Age = (TextView)convertView.findViewById(R.id.studentage);
viewHolder.Id = (TextView)convertView.findViewById(R.id.rowid);
viewHolder.Image = (CircularImageView)convertView.findViewById(R.id.imgFood);
convertView.setTag(viewHolder);
}else
{
viewHolder = (ViewHolder)convertView.getTag();
}
this.cur.moveToPosition(position);
viewHolder.name.setText(this.cur.getString(this.cur.getColumnIndex(SQLiteHelper.NAME)));
viewHolder.Age.setText(this.cur.getString(this.cur.getColumnIndex(SQLiteHelper.AGE)));
viewHolder.Id.setText(this.cur.getString(this.cur.getColumnIndex(SQLiteHelper._ID)));
Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
Picasso.with(mContext)
.load(new File(String.valueOf(jg)))
.placeholder(R.drawable.profile)
.resize(800, 800)
.centerCrop()
.into(viewHolder.Image);
return convertView;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// Dont need to do anything here
return null;
}
static class ViewHolder
{
TextView name;
TextView Age;
TextView Id;
CircularImageView Image;
}
}
Спасибо всем за помощь.
2 ответа
Вы можете использовать библиотеку Picasso для отображения изображений.
compile 'com.squareup.picasso:picasso:2.5.2'
И в вашем адаптере что-то вроде этого:
Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
Picasso.with(context).load(jg).into(viewHolder.Image);
Для контекста
public class MyNiftyAdapter extends CursorAdapter{
private LayoutInflater mInflater;
private Cursor cur;
private Context mContext;
public MyNiftyAdapter(Context context, Cursor c) {
super(context,c);
this.mInflater = LayoutInflater.from(context);
this.mContext= context;
this.cur = c;
}
public MyNiftyAdapter(Context context, Cursor c, boolean autoRequery)
{
super(context, c, autoRequery);
this.mInflater = LayoutInflater.from(context);
this.cur = c;
this.mContext= context;
}
затем используйте:
Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
Picasso.with(mContext).load(jg).into(viewHolder.Image);