1

我在使用自定义 cursorAdapter 和 AsyncTask 时遇到了一些麻烦。我想先在 asyctask 中设置 listView 和适配器,然后再从数据库中查询数据。但是适配器中的第一次游标是空的,它会抛出一个异常。在我的自定义光标适配器中如何处理这种情况?将 setAdapter 重新定位到 onPostExecute 也没有帮助。任何建议也会很棒。

主要活动:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    ConversationsListCursorAdapter conversationsListCursorAdapter = new ConversationsListCursorAdapter(context, R.layout.conversations_list_item, null, 0);
    conversationsListView = (ListView) findViewById(android.R.id.list);
    conversationsListView.setAdapter(conversationsListCursorAdapter);

}

@Override
protected void onResume() {
    super.onResume();
    new GetConversationsTask().execute((Object[]) null);
}

@Override
protected void onStop() {
    Cursor cursor = conversationsListCursorAdapter.getCursor();
    if (cursor != null) { 
        cursor.close();
    }

    conversationsListCursorAdapter.changeCursor(null);
    super.onStop();
}

private class GetConversationsTask extends AsyncTask<Object, Object, Cursor> {
    @SuppressLint("NewApi")
    @Override
    protected Cursor doInBackground(Object... params) {
        Uri uri = ClouContentProvider.CONVERSATIONS_CONTENT_URI;
        Cursor cursor = null;

        if (android.os.Build.VERSION.SDK_INT < 11) {
            cursor = getContentResolver().query(uri, null, null, null, null);
        } else {
            CursorLoader cursorLoader = new CursorLoader(context, uri, null, null, null, null);
            cursor = cursorLoader.loadInBackground();
        }

        return cursor;
    }

    @Override
    protected void onPostExecute(Cursor cursor) {
        conversationsListCursorAdapter.changeCursor(cursor);
        cursor.close();
    }
}

光标适配器:

public class ConversationsListCursorAdapter extends CursorAdapter {

    private final Cursor mCursor;
    private final Context mContext;
    private final int mLayout;
    private final int mSnippetIndex;
    private final int mDateIndex;
    private final int mMessageCount;
    private final int mRead;
    private final LayoutInflater mLayoutInflater;

    //private static final String TAG = ConversationsListCursorAdapter.class.getSimpleName();

    static class ViewHolder {
        TextView tvBody;
        TextView tvPerson;
        TextView tvCount;
        TextView tvDate;
        QuickContactBadge ivPhoto;
        View vRead;
    }

    public ConversationsListCursorAdapter(Context context, int layout, Cursor cursor, int flags) {
        super(context, cursor, flags);

        this.mContext = context;
        this.mLayout = layout;
        this.mCursor = cursor;
        this.mSnippetIndex = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.SNIPPET);
        this.mDateIndex = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.DATE);
        this.mMessageCount = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.MESSAGE_COUNT);
        this.mRead = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.READ);
        this.mLayoutInflater = LayoutInflater.from(mContext);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {

        View rowView = mLayoutInflater.inflate(mLayout, parent, false);

        ViewHolder holder = new ViewHolder();
        holder.tvBody = (TextView) rowView.findViewById(R.id.body);
        holder.tvPerson = (TextView) rowView.findViewById(R.id.addr);
        holder.tvCount = (TextView) rowView.findViewById(R.id.count);
        holder.tvDate = (TextView) rowView.findViewById(R.id.date); 
        holder.ivPhoto = (QuickContactBadge) rowView.findViewById(R.id.photo);
        holder.vRead  = (View) rowView.findViewById(R.id.read);

        rowView.setTag(holder);

        return rowView;
    }

    @Override
    public void bindView(View v, Context context, Cursor cursor) {

        ViewHolder holder = (ViewHolder) v.getTag();

        String cBody = cursor.getString(mSnippetIndex);
        Integer cCount = cursor.getInt(mMessageCount);
        Long cDate = cursor.getLong(mDateIndex);
        Integer cRead = cursor.getInt(mRead);

        holder.tvBody.setText(cBody);

        if (cCount < 0) {
            holder.tvCount.setText("");
        } else {
            holder.tvCount.setText("(" + cCount + ")");
        }

        if (cRead == 0) {
            holder.vRead.setVisibility(View.VISIBLE);
        } else {
            holder.vRead.setVisibility(View.INVISIBLE);
        }

        holder.tvDate.setText(ClouUtils.getDate(context, cDate));
        holder.tvPerson.setText(cursor.getString(mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.CANONICAL)));
        holder.ivPhoto.setImageResource(R.drawable.ic_contact_picture);
        holder.ivPhoto.setVisibility(View.VISIBLE);

    }
4

1 回答 1

0
@Override
protected void onPostExecute(Cursor cursor) {
    // First check if it's null
    if(cursor !=null){
        // use swap to get the old cursor and close it
        Cursor oldC = conversationsListCursorAdapter.swapCursor(cursor);
        if(oldC != null){
           oldC.close();
        }
       // DO NOT CLOSE THE NEW CURSOR
       // this one you must close whenever the list goes onPause(); but not before
    }
}
于 2013-04-12T13:07:00.777 回答