android– 具有多个ListFragments和SQLite游标战斗的SherlockFragmentActivity

android– 具有多个ListFragments和SQLite游标战斗的SherlockFragmentActivity,第1张

概述我正在使用一个扩展SherlockFragmentActivity的Activity,它有3个标签.3个选项卡是实现LoaderManager.LoaderCallbacks的ListFragments.Activity的OnCreate方法像这样加载选项卡bar.addTab(bar.newTab().setTag("venues_list").setText(getString(R.string.list_venue

我正在使用一个扩展SherlockFragmentActivity的Activity,它有3个标签. 3个选项卡是实现LoaderManager.LoaderCallbacks的ListFragments. Activity的OnCreate方法像这样加载选项卡

bar.addTab(bar.newTab()    .setTag("venues_List")    .setText(getString(R.string.List_venues_header))    .setTabListener(new TabListener<VenueListFragment>(        this, getString(R.string.List_invites_header), VenueListFragment.class, null)));// I do the EXACT same thing for the other two tabs, using their respective ListFragmentsif (savedInstanceState != null) {    bar.setSelectednavigationItem(savedInstanceState.getInt("tab", 0));}

我正在加载标签的布局非常简单:

<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID"    androID:layout_wIDth="fill_parent"    androID:layout_height="fill_parent"    androID:orIEntation="vertical" ></linearLayout>

每个选项卡都有一个与此相同的类,只是称为不同的类:

import androID.content.Context;import androID.content.SharedPreferences;import androID.database.Cursor;import androID.os.Bundle;import androID.support.v4.app.LoaderManager;import androID.support.v4.content.Loader;import androID.support.v4.Widget.CursorAdapter;import androID.support.v4.Widget.SimpleCursorAdapter;import androID.vIEw.VIEw;import androID.Widget.AdapterVIEw;import androID.Widget.AdapterVIEw.OnItemClickListener;import androID.Widget.ListVIEw;import androID.Widget.Toast;import com.actionbarsherlock.app.SherlockListFragment;import com.lateral.oursvp.R;import com.lateral.oursvp.database.SimpleCursorLoader;import com.lateral.oursvp.database.VenuesDataSource;/** * @author rabbott * */public class VenueListFragment extends SherlockListFragment implements LoaderManager.LoaderCallbacks<Cursor> {      SharedPreferences appPreferences;    private CursorAdapter cursorAdapter;    @OverrIDe    public voID onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);    }    @OverrIDe    public voID onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        // bind the columns of the cursor to the List        String[] from = new String[] { VenuesDataSource.KEY_name, VenuesDataSource.KEY_DESCRIPTION };        int[] to = new int[] { R.ID.List_item_Title, R.ID.List_item_subTitle };        cursorAdapter = new SimpleCursorAdapter( getActivity(), R.layout.List_item, null, from, to, 0);        // retrIEve the ListvIEw to populate        ListVIEw lv = (ListVIEw) getActivity().findVIEwByID(androID.R.ID.List);        // set the adapter on the ListvIEw        lv.setAdapter(cursorAdapter);        // click event for each row of the List        lv.setonItemClickListener(new OnItemClickListener() {            public voID onItemClick(AdapterVIEw<?> arg0, VIEw vIEw,                    int position, long ID) {                Cursor cursor = cursorAdapter.getCursor();                cursor.movetoposition(position);                Toast.makeText(getActivity(), "Tapped row " + position + "!", Toast.LENGTH_SHORT).show();            }        });        // Start out with a progress indicator.        setListShown(false);        // load the data        getActivity().getSupportLoaderManager().initLoader(0, null, this);    }    public Loader<Cursor> onCreateLoader(int loaderID, Bundle args) {        return new VenueCursorLoader(getActivity());    }    public voID onl oadFinished(Loader<Cursor> loader, Cursor cursor) {        cursorAdapter.swapCursor(cursor);        // the List should Now be shown        if (isResumed()) {            setListShown(true);        } else {            setListShownNoAnimation(true);        }    }    public voID onl oaderreset(Loader<Cursor> loader) {        cursorAdapter.swapCursor(null);    }    public static final class VenueCursorLoader extends SimpleCursorLoader {        Context mContext;        public VenueCursorLoader(Context context) {            super(context);            mContext = context;        }        @OverrIDe        public Cursor loadInBackground() {            VenuesDataSource datasource = new VenuesDataSource(mContext);            return datasource.getAllVenues(((EventActivity) mContext).getEventID());        }    }}

它使用此处定义的SimpleCursorLoaded:

import androID.content.Context;import androID.database.Cursor;import androID.support.v4.content.AsyncTaskLoader;public abstract class SimpleCursorLoader extends AsyncTaskLoader<Cursor> {    private Cursor mCursor;    public SimpleCursorLoader(Context context) {        super(context);    }    /* Runs on a worker thread */    @OverrIDe    public abstract Cursor loadInBackground();    /* Runs on the UI thread */    @OverrIDe    public voID deliverResult(Cursor cursor) {        if (isreset()) {            // An async query came in while the loader is stopped            if (cursor != null) {                cursor.close();            }            return;        }        Cursor oldCursor = mCursor;        mCursor = cursor;        if (isstarted()) {            super.deliverResult(cursor);        }        if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) {            oldCursor.close();        }    }    /**     * Starts an asynchronous load of the contacts List data. When the result is ready the callbacks     * will be called on the UI thread. If a prevIoUs load has been completed and is still valID     * the result may be passed to the callbacks immediately.     * <p/>     * Must be called from the UI thread     */    @OverrIDe    protected voID onStartLoading() {        if (mCursor != null) {            deliverResult(mCursor);        }        if (takeContentChanged() || mCursor == null) {            forceLoad();        }    }    /**     * Must be called from the UI thread     */    @OverrIDe    protected voID onStopLoading() {        // Attempt to cancel the current load task if possible.        cancelLoad();    }    @OverrIDe    public voID onCanceled(Cursor cursor) {        if (cursor != null && !cursor.isClosed()) {            cursor.close();        }    }    @OverrIDe    protected voID onreset() {        super.onreset();        // Ensure the loader is stopped        onStopLoading();        if (mCursor != null && !mCursor.isClosed()) {            mCursor.close();        }        mCursor = null;    }}

我遇到的问题是,当我选择说..第二个选项卡(第三个选项卡执行相同)时,它会尝试加载光标,但是当它尝试填充List_items时,我收到错误说

E/AndroIDRuntime(2055): java.lang.IllegalArgumentException: column 'GIVEN_VARIABLE' does not exist

在设置了几个断点后,我发现它试图使用的光标是来自第一个标签的光标,它在充气时加载很好,但显然没有被关闭,显然是在尝试再次使用,即使我(我想从getAllVenues()发送一个不同的光标

编辑:这是堆栈跟踪发送给我的最后一个地方
当我设置一些断点时,我可以看到这里提供的光标是来自第一个选项卡的光标,而不是Venue选项卡的光标.

编辑:VenuesDataSource代码显示getAllVenues方法

import org.Json.JsONArray;import org.Json.JsONException;import org.Json.JsONObject;import androID.content.ContentValues;import androID.content.Context;import androID.database.Cursor;import androID.database.sqlException;import androID.util.Log;/** * @author rabbott * */public class VenuesDataSource extends appsqliteHelper {    public static final String table_name               = "venues";    // venue columns    public static final String KEY_name                 = "name";    public static final String KEY_DESCRIPTION          = "description";    public static final String KEY_START_TIME           = "start_time";    public static final String KEY_ADDRESS              = "address";    public static final String KEY_CITY                 = "city";    public static final String KEY_STATE                = "state";    public static final String KEY_ZIP                  = "postal_code";    public static final String KEY_LNG                  = "lng";    public static final String KEY_LAT                  = "lat";    public static final String KEY_PHONE                = "phone";    public static String ColUMNS_VENUES[] = {         DatabaseConstants.KEY_ROWID,         DatabaseConstants.KEY_EVENT_ID,        KEY_name,         KEY_DESCRIPTION,         KEY_START_TIME,        KEY_ADDRESS,         KEY_CITY,         KEY_STATE,        KEY_ZIP,         KEY_LNG,         KEY_LAT,         KEY_PHONE,        DatabaseConstants.KEY_CREATED_AT    };    public static final String CREATE_STATEMENT = "CREATE table IF NOT EXISTS " + table_name + " ("            + "_ID              INTEGER PRIMARY KEY autoINCREMENT,"            + "event_ID         INTEGER NOT NulL,"            + "name             TEXT NOT NulL,"            + "description      TEXT,"            + "start_time       TEXT,"            + "address          TEXT NOT NulL,"            + "city             TEXT NOT NulL,"            + "state            TEXT NOT NulL,"            + "postal_code      TEXT,"            + "lat              TEXT,"            + "lng              TEXT,"            + "phone            TEXT,"            + "created_at       TEXT);";    public VenuesDataSource(Context context) {        super(context);        Log.i("VenueDataSource", "Constructor");    }    // create a new contact locally    public long createVenue(Integer venue_ID, Integer event_ID, String name, String description, String start_time, String address, String city, String state, String postal_code, String lat, String lng, String phone, String created_at) {        ContentValues initialValues = new ContentValues();        initialValues.put(DatabaseConstants.KEY_ROWID, event_ID);        initialValues.put(DatabaseConstants.KEY_EVENT_ID, event_ID);        initialValues.put(KEY_name, name);        initialValues.put(KEY_DESCRIPTION, description);        initialValues.put(KEY_START_TIME, start_time);        initialValues.put(KEY_ADDRESS, address);        initialValues.put(KEY_CITY, city);        initialValues.put(KEY_STATE, state);        initialValues.put(KEY_ZIP, postal_code);        initialValues.put(KEY_PHONE, phone);        initialValues.put(KEY_LAT, lat);        initialValues.put(KEY_LNG, lng);        initialValues.put(DatabaseConstants.KEY_CREATED_AT, created_at);        return getWritableDatabase().insert(table_name, null, initialValues);    }    // retrIEve a venue from the local database    public Cursor getVenue(long rowID) throws sqlException {        Cursor mCursor = getWritableDatabase().query(true, table_name, ColUMNS_VENUES, DatabaseConstants.KEY_ROWID + "=" + rowID, null, null, null, null, null);        if (mCursor != null) {            mCursor.movetoFirst();        }        return mCursor;    }    // update a local venue    public long updateVenue(Integer venue_ID, Integer event_ID, String name, String description, String start_time, String address, String city, String state, String postal_code, String lat, String lng, String phone) {        ContentValues initialValues = new ContentValues();        initialValues.put(DatabaseConstants.KEY_EVENT_ID, event_ID);        initialValues.put(KEY_name, name);        initialValues.put(KEY_DESCRIPTION, description);        initialValues.put(KEY_START_TIME, start_time);        initialValues.put(KEY_ADDRESS, address);        initialValues.put(KEY_CITY, city);        initialValues.put(KEY_STATE, state);        initialValues.put(KEY_ZIP, postal_code);        initialValues.put(KEY_PHONE, phone);        initialValues.put(KEY_LAT, lat);        initialValues.put(KEY_LNG, lng);        return getWritableDatabase().update(table_name, initialValues, "_ID=?", new String[] { Long.toString(venue_ID) });    }    // delete a local venue    public boolean deleteVenue(long rowID) {        return (getWritableDatabase().delete(table_name, DatabaseConstants.KEY_ROWID + "=" + rowID, null) > 0);    }    // retrIEve all local venues    public Cursor getAllVenues(long event_ID) {        Cursor mCursor = getWritableDatabase().query(true, table_name, ColUMNS_VENUES, DatabaseConstants.KEY_EVENT_ID + "=" + event_ID,                 null, null, null, null, null);        return mCursor;     }    public boolean venueExists(int venue_ID) {        Cursor mCursor = getWritableDatabase().query(true, table_name, ColUMNS_VENUES, DatabaseConstants.KEY_ROWID + "=" + venue_ID,                    null, null, null, null, null);        if (mCursor.getCount() == 0) {            mCursor.close();            return false;        } else {            mCursor.close();            return true;        }    }    public voID parseVenue(JsONObject venueJson) throws JsONException {        boolean venue_exists = false;        int event_ID, venue_ID;        String venue_name, venue_description, start_time, venue_address, venue_city, venue_state, venue_postal_code, lat, lng, venue_phone, created_at;        venue_ID            = venueJson.getInt(DatabaseConstants.KEY_REMOTE_ID);        event_ID            = venueJson.getInt(DatabaseConstants.KEY_EVENT_ID);        venue_name          = venueJson.getString(KEY_name);        venue_description   = venueJson.getString(KEY_DESCRIPTION);        start_time          = venueJson.getString(KEY_START_TIME);        venue_address       = venueJson.getString(KEY_ADDRESS);        venue_city          = venueJson.getString(KEY_CITY);        venue_state         = venueJson.getString(KEY_STATE);        venue_postal_code   = venueJson.getString(KEY_ZIP);        venue_phone         = venueJson.getString(KEY_PHONE);        lat                 = venueJson.getString(KEY_LAT);        lng                 = venueJson.getString(KEY_LNG);        created_at          = venueJson.getString(DatabaseConstants.KEY_CREATED_AT);        // check to see if this venue already exists        venue_exists = this.venueExists(venue_ID);        if (venue_exists == true) {            this.updateVenue(                    venue_ID,                     event_ID,                     venue_name,                    venue_description,                    start_time,                    venue_address,                     venue_city,                     venue_state,                    venue_postal_code,                     lat,                    lng,                     venue_phone);        } else {            this.createVenue(                    venue_ID,                    event_ID,                    venue_name,                    venue_description,                    start_time,                    venue_address,                     venue_city,                    venue_state,                    venue_postal_code,                     lat,                    lng,                    venue_phone,                    created_at);        }    }    public voID parseVenues(JsONArray venuesArray) throws JsONException {        JsONObject venueJson;        for (int i = 0; i < venuesArray.length(); i++) {            // Iterate through each venue            venueJson = venuesArray.getJsONObject(i);            this.parseVenue(venueJson);        }    }}

解决方法:

问题是initLoader方法的第一个参数是唯一标识要加载的每个项目的方法,我的所有项目都设置为相同的(0)值 – 将它们更改为修复问题的唯一值.

总结

以上是内存溢出为你收集整理的android – 具有多个ListFragments和SQLite游标战斗的SherlockFragmentActivity全部内容,希望文章能够帮你解决android – 具有多个ListFragments和SQLite游标战斗的SherlockFragmentActivity所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1109896.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-29
下一篇 2022-05-29

发表评论

登录后才能评论

评论列表(0条)

保存