AsyncTask и пользовательский CursorAdaper

У меня проблемы с пользовательским курсоромAdapter и AsyncTask. Я хотел сначала настроить listView и адаптер, а затем в asyctask запрашивать данные из базы данных. Но в первый раз курсор в адаптере имеет значение null и выдает исключение. Как можно справиться с такой ситуацией в моем пользовательском адаптере курсора? Не помогло и перемещение 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);

    }

person SerijVeter    schedule 12.04.2013    source источник


Ответы (1)


person    schedule
comment
Спс за совет. Я слишком молод в андроиде. Не решение, а хороший совет. Tnx снова. - person SerijVeter; 12.04.2013
comment
ну, я думал, что решу, основываясь на том, что вы сказали. Но в первый раз курсор в адаптере равен нулю, и он выдает исключение. Вы проверяете значение null перед его использованием. - person Budius; 12.04.2013
comment
Понимаю. Итак, приложение запускается в первый раз, база данных пуста. И насколько я понимаю, моя проблема начинается с моего адаптера, потому что курсор равен нулю - база данных еще не создана. Моя основная идея заключалась в том, что cursorAdapter можно назвать как SimpleCursorAdapter с нулевым курсором. - person SerijVeter; 12.04.2013
comment
ну... нет причин создавать адаптер, если у вас все еще нет данных для отображения в пользовательском интерфейсе. Поэтому, вероятно, вам следует создавать его только после того, как onPostExecute вернет ненулевой курсор с длиной > 0. - person Budius; 12.04.2013
comment
Может быть, я не понимаю всего этого. Когда приложение запускается в первый раз, база данных должна быть создана, а данных в этот момент нет. Но getColumnIndex должен работать, а listView должен быть пустым. И он работает корректно без AsyncTask. И не стал с этим. - person SerijVeter; 12.04.2013
comment
Проще: запуск приложения, создание адаптера с нулевым курсором (база данных еще не установлена), асинхронный запрос к базе данных для списка разговоров, создание базы данных с помощью провайдеров, база данных установлена ​​и пуста, данные запроса, курсор не нулевой (нет данных, но курсор не нулевой). Это была моя мысль. - person SerijVeter; 12.04.2013