【问题标题】:How to close Cursor opened in Adapter class?如何关闭在适配器类中打开的光标?
【发布时间】:2012-04-24 18:15:45
【问题描述】:

在我的应用程序中,我有一个在 gridView 中显示图像的活动。所以我使用了一个扩展 BaseAdapter 的适配器类。在那个适配器类中,我打开了一个游标并从 getView() 方法返回图像。

所以现在我的问题是当我遇到异常时应该在哪里关闭光标。我不能使用 startManagingCursor() 因为它已被弃用。任何其他解决方案将不胜感激。

我的 onCreate 方法

public void onCreate(Bundle bundle){
    super.onCreate(bundle);
    setContentView(R.layout.splitted_grid);
    System.out.println("started new splittedimageactivity");
    //splittedBitmaps = getIntent().getParcelableArrayListExtra("splitted_images");
    int size = getIntent().getIntExtra("image_numbers", 0);
    int width = getIntent().getIntExtra("width", 0);
    int height = getIntent().getIntExtra("height", 0);
    gridView = (GridView) findViewById(R.id.image_grid_view);
    SplittedImageAdapter s = new SplittedImageAdapter(this, size, width, height);
    gridView.setAdapter(s);
    gridView.setNumColumns((int) Math.sqrt(size));//splittedBitmaps.size()));
    s.close();// This causes exception trying to re-open already closed cursor. If I remove this, then exception is your cursor is not closed, call close() explicitly 
}

我的适配器类

public class SplittedImageAdapter extends BaseAdapter{

private Context mContext;
//private List<Bitmap> mSplittedBitmaps;
public ViewGroup mParentView = null;
private int noOfImages, imageWidth, imageHeight;
private Cursor mCursor;

public SplittedImageAdapter(Context c, int size, int w, int h){
    mContext = c;
    noOfImages = size;
    imageWidth = w;
    imageHeight = h;
    DBAdapter db = new DBAdapter(c);
    db.open();
    mCursor = db.getAllImages();
    System.out.println(mCursor+"cursor opened");

}

@Override
public int getCount() {
    return noOfImages;//mSplittedBitmaps.size();
}

@Override
public Object getItem(int position) {
    return position;//mSplittedBitmaps.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

    mParentView = parent;
    ImageCell imageView = null;
    if(convertView == null){
        imageView = new ImageCell(mContext);
        imageView.setLayoutParams(new GridView.LayoutParams(imageWidth-4, imageHeight-4));//65,65));//SplittedImageActivity.splittedBitmaps.get(position).getWidth()-4, SplittedImageActivity.splittedBitmaps.get(position).getHeight()-4));
        imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
        imageView.setPadding(0, 0, 0, 0);
    }else{
        imageView = (ImageCell) convertView;
    }
    imageView.mCellNumber = position;
    imageView.mGrid = (GridView) mParentView;
    imageView.setId(position);
    if(position == noOfImages-1){//SplittedImageActivity.splittedBitmaps.size()-1 == position){
        imageView.mEmpty = true;
        imageView.setBackgroundResource(R.color.cell_empty);
    }
    else{
        //System.out.println(mCursor.getCount());
        mCursor.moveToPosition(position);
        Bitmap b = BitmapFactory.decodeFile(mCursor.getString(4));//"/sdcard/Android/data/com.softtrends.puzzle/files/Pictures/image"+position+".jpg");
        imageView.setImageBitmap(b);//SplittedImageActivity.splittedBitmaps.get(position));
        imageView.mEmpty = false;
    }
    imageView.setOnClickListener((OnClickListener) mContext);
    imageView.setOnLongClickListener((OnLongClickListener) mContext);
    return imageView;
}

public void close(){
    mCursor.close();
}
}

【问题讨论】:

  • 在我确定我已经收到所有我需要的数据之后,我会调用 Cursor.close(),或者在我的 BaseAdapter 子类上创建一个名为 close() 的包装器方法,该方法调用我的光标的 close 方法。我不确定你是如何设置你的应用程序或 BaseAdapter 子类的,所以我无法提供进一步的帮助。
  • 这取决于你如何获得这个光标......如果它来自 ConetntProvider 你可以使用developer.android.com/reference/android/content/… 在其他情况下你可以在 onDestroy of activity 中关闭光标
  • @Selvin 光标对象是 BaseAdapter 子类的本地对象,我将如何在与该适配器关联的 Activity 的 onDestroy 中关闭它?
  • 如果您使用游标,为什么不使用 CursorAdapter 作为适配器的基础...它将 Cusros 作为构造函数的参数,所以在使用 CursorAdapter 的情况下,您应该在 Adapter 所在的 Activity 中创建游标已创建...它包含 swapCursor() 方法,因此如果您重新查询,则无需创建新适配器...
  • Selvin 的想法是解决这个问题的理想方案

标签: android sqlite cursor


【解决方案1】:

发生这种情况是因为您不是专门调用 close() 方法。

在 Adapter 的 getView() 方法中返回 imageView 之前执行此操作,并删除 s.close() 因为 s 是适配器而不是游标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-28
    • 2021-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多