[英]OutOfMemoryError when setting Uri with setImageURI
The user select a image, the path of the image is then stored in my SQLite database. 用户选择一个图像,然后将图像的路径存储在我的SQLite数据库中。 I then populate the text/images from SQLite in a GridView
using a CursorAdapter: 然后,我使用CursorAdapter在GridView
填充SQLite中的文本/图像:
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;
}
}
When I select large images I get a out of memory error: 当我选择大图像时,我得到一个内存不足错误:
java.lang.OutOfMemoryError: Failed to allocate a 21566748 byte allocation with 8448604 free bytes and 8MB until OOM
I have seen that the bitmap should be scaled down, but I'm just using the Uri
of the file and displaying it. 我已经看到位图应该缩小,但我只是使用文件的Uri
并显示它。 Is there anyway to avoid this issue as I don't want to save another(compressed) file to the device? 有没有办法避免这个问题,因为我不想将另一个(压缩)文件保存到设备?
I have tried android:hardwareAccelerated="false"
in manifest. 我在manifest中尝试过android:hardwareAccelerated="false"
。
This is what worked for me: 这对我有用:
I ended up using picasso as the answers suggested, but something important to note is that when loading a URI
from device is to load the URI
like this: 我最后使用picasso作为建议的答案,但需要注意的一点是, 从设备加载URI
时要加载这样的URI
:
Picasso.with(mContext)
.load(new File(String.valueOf(Uri)))
.placeholder(R.drawable.profile)
.resize(800, 800)
.centerCrop()
.into(viewHolder.Image);
note that I used .load(new File(String.valueOf(Uri)))
instead of .load(uri)
. 请注意我使用.load(new File(String.valueOf(Uri)))
而不是.load(uri)
。 If you load the URI
directly the view will return empty. 如果直接加载URI
,则视图将返回空。
If you load a image from a url , it should be loaded like this: 如果从网址加载图片 ,则应按如下方式加载:
Picasso.with(mContext)
.load(URL)
.placeholder(R.drawable.profile)
.resize(800, 800)
.centerCrop()
.into(viewHolder.Image);
So my adapter ended up looking like this: 所以我的适配器最终看起来像这样:
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;
}
}
Thank you all for the help. 谢谢大家的帮助。
You can use Picasso library to display images. 您可以使用Picasso库来显示图像。
compile 'com.squareup.picasso:picasso:2.5.2'
And in your adapter something like this : 在您的适配器中这样的事情:
Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
Picasso.with(context).load(jg).into(viewHolder.Image);
For Context 对于上下文
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;
}
an then use : 然后使用:
Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
Picasso.with(mContext).load(jg).into(viewHolder.Image);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.