使用setImageURI设置Uri时的OutOfMemoryError

时间:2017-09-29 09:11:46

标签: java android sqlite android-memory

用户选择图像后,图像的路径将存储在我的SQLite数据库中。然后,我使用CursorAdapter在function edit_book(){ $id = $this->input->post('id'); $editBook = array( 'id' => $this->input->post('id'), 'book_title' => $this->input->post('book_title'), 'category' => $this->input->post('category'), 'author' => $this->input->post('author') ): $this->m_profile->edit_book($data1, $data, 'book_data'); $url = base_url('app/book/'.$id); redirect( $url) } function book($id = NULL) { //get record using $id; } 中填充SQLite中的文本/图像:

GridView

当我选择大图像时,出现内存不足错误:

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

这对我有用:

我最终使用picasso作为建议的答案,但需要注意的一点是,从设备加载 android:hardwareAccelerated="false" 时要加载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

所以我的适配器最终看起来像这样:

Picasso.with(mContext)
            .load(URL)
            .placeholder(R.drawable.profile)
            .resize(800, 800)
            .centerCrop()
            .into(viewHolder.Image);

谢谢大家的帮助。

2 个答案:

答案 0 :(得分: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);

答案 1 :(得分:1)

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;

}

然后使用:

Uri jg = Uri.parse(this.cur.getString(this.cur.getColumnIndex("imagepath")));
Picasso.with(mContext).load(jg).into(viewHolder.Image);