我已经阅读了与此相似的其他问题,但无法解决此问题。
我正在尝试查询数据库并使用结果填充列表视图。正如您在代码中看到的,我已经以几种不同的方式完成了这项工作,即。返回数组列表等。使用此特定列表,我试图返回一个光标,然后将其发送到自定义适配器。我收到以下错误:
07-11 10:55:27.192 30405-30405/? E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.bkane56.practice.practiceapp, PID: 30405
java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteQuery: SELECT stop_name, stop_lat, stop_lon, _id FROM stops
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:58)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
at android.widget.CursorAdapter.getView(CursorAdapter.java:245)
at android.widget.AbsListView.obtainView(AbsListView.java:2347)
at android.widget.ListView.measureHeightOfChildren(ListView.java:1270)
at android.widget.ListView.onMeasure(ListView.java:1182)
at android.view.View.measure(View.java:17547)
at android.widget.RelativeLayout.measureChildHorizontal(RelativeLayout.java:727)
at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:463)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1436)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:722)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:613)
at android.view.View.measure(View.java:17547)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5535)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:436)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2615)
at android.view.View.measure(View.java:17547)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2015)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1173)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1379)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1061)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5885)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
at android.view.Choreographer.doCallbacks(Choreographer.java:580)
at android.view.Choreographer.doFrame(Choreographer.java:550)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5257)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
这是我的activty.class:
package com.bkane56.practice.practiceapp;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;
public class NavigateActivity extends Activity {
private MetroLinkDatabaseHelper myHelper =
MetroLinkDatabaseHelper.getInstance(this);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_navigate);
populateLocationLIst();
}
private void openDB() {
myHelper.open();
}
private void closeDB() {
myHelper.close();
}
public void populateLocationLIst( ) {
Cursor cursor = myHelper.getAllLcations();
ListView lvItems = (ListView) findViewById(R.id.lvLocations);
LocationCursorAdaptor locationAdaptor = new LocationCursorAdaptor(this, cursor);
lvItems.setAdapter(locationAdaptor);
cursor.close();
}
// ....Menu methods left out of this question but present in class.
}
My Helper.class如下:
package com.bkane56.practice.practiceapp;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public class MetroLinkDatabaseHelper extends SQLiteOpenHelper {
private Context mycontext;
private String stopName;
private String sqlQueryTimes;
private static MetroLinkDatabaseHelper myInstance;
private static String DB_PATH = "data/data/com.bkane56.practice.practiceapp/databases/";
private static String DB_NAME = "metrolink2.db";
public static SQLiteDatabase myDataBase;
public static synchronized MetroLinkDatabaseHelper getInstance(Context context) {
// Using a singleton to minmize the chance of opening multiple
// decreasing any chance of memory leak
if(myInstance == null) {
myInstance = new MetroLinkDatabaseHelper(context);
}
return myInstance;
}
private MetroLinkDatabaseHelper(Context context) {
super(context, DB_NAME, null, 1);
this.mycontext = context;
boolean dbexist = checkdatabase();
if (dbexist) {
} else {
System.out.println("Database doesn't exist");
try {
createdatabase();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
// Create (copy the original in assets) if not exist using copydatabase
public void createdatabase() throws IOException {
boolean dbexist = checkdatabase();
if (dbexist) {
} else {
this.getReadableDatabase();
try {
copydatabase();
} catch (IOException e) {
throw new Error("Error copying database");
}
}
}
// Check if the Android database has been created from attached database
private boolean checkdatabase() {
boolean checkdb = false;
try {
String myPath = DB_PATH + DB_NAME;
File dbfile = new File(myPath);
checkdb = dbfile.exists();
if (!checkdb) {
System.out.println("THE DATA BASE DOES NOT EXIST");
}
} catch (SQLiteException e) {
System.out.println("Database doesn't exist");
}
return checkdb;
}
// copies the data from the metroLink db in assets to data/data....metrolink.db
public void copydatabase() throws IOException {
// Open your local db as the input stream
InputStream myinput = mycontext.getAssets().open(DB_NAME);
String outfilename = DB_PATH + DB_NAME;
// Open the empty db as the output stream
OutputStream myoutput = new FileOutputStream(outfilename);
// buffered reader to write new database
byte[] buffer = new byte[1024];
int length;
while ((length = myinput.read(buffer)) > 0) {
myoutput.write(buffer, 0, length);
}
// Close the streams
myoutput.flush();
myoutput.close();
myinput.close();
}
public static SQLiteDatabase open() {
// Open the database
String mypath = DB_PATH + DB_NAME;
myDataBase = SQLiteDatabase.openDatabase(mypath, null,
SQLiteDatabase.OPEN_READONLY);
return myDataBase;
}
public synchronized void close() {
super.close();
myDataBase.close();
}
public void delete() {
//Delete Existing Database
File mypath = new File(DB_PATH + DB_NAME);
myDataBase.close();
System.out.println("DELETING THE EXISTING DATABASE");
myDataBase.deleteDatabase(mypath);
}
// returns a list of all the stops sorted by longitude west to east
public List<String> getAllStops() {
final String TABLE = "stops";
final String[] COLUMN = new String[]{"stop_name"};
final String ORDER_BY = "stop_name";
String myPath = DB_PATH + DB_NAME;
List<String> stopList = new ArrayList<String>();
// open data base
open();
Cursor c = myDataBase.query(TABLE, COLUMN, null, null, null, null, ORDER_BY, null);
// Cursor c = myDataBase.rawQuery("select stop_name as _id from stops", null);
if (c.moveToFirst()) {
do {
stopList.add(c.getString(0));
}
while (c.moveToNext());
if (c != null && !c.isClosed()) {
c.close();
}
}
myDataBase.close();
return stopList;
}
// Returns a cursor with stop_name, stop_lat, stop_lon, _id from metrolink2.db
public Cursor getAllLcations() {
// populate list stopLon, list stopLat, list stopName
List<String> stopLL = new ArrayList<>();
List<List<String>> nameLatLong = new ArrayList<>();
// open database
open();
Cursor c = myDataBase.rawQuery("SELECT stop_name, stop_lat, stop_lon, _id " +
"FROM stops", null);
if (c.moveToFirst()) {
do {
stopLL.add(c.getString(0));
stopLL.add(c.getString(1));
stopLL.add(c.getString(2));
stopLL.add(c.getString(3));
nameLatLong.add(stopLL);
stopLL.clear();
}
while (c.moveToNext());
// if (c != null && !c.isClosed()) {
// c.close();
// }
}
myDataBase.close();
return c;
}
// gets next 3 stop times
public List<String> getStopTimes(String sqlQueryTimes) {
this.sqlQueryTimes = sqlQueryTimes;
List<String> stopTime = new ArrayList<String>();
String myPath = DB_PATH + DB_NAME;
// open database
open();
Cursor c = myDataBase.rawQuery(sqlQueryTimes, null);
if (c.moveToFirst()) {
do {
stopTime.add(c.getString(0));
}
while (c.moveToNext());
if (c != null && !c.isClosed()) {
c.close();
}
}
myDataBase.close();
return stopTime;
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
最后我的adapter.class是这样的:
package com.bkane56.practice.practiceapp;
import android.content.Context;
import android.database.Cursor;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.TextView;
public class LocationCursorAdaptor extends CursorAdapter {
public LocationCursorAdaptor(Context context, Cursor cursor) {
super(context, cursor, 0);
}
// The newView method is used to inflate and return a new view
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.lv_navigation, parent, false);
}
// Binds the data from db to the text views in list view
@Override
public void bindView(View view, Context context, Cursor cursor) {
TextView tvStopName = (TextView) view.findViewById(R.id.tvStopName);
TextView tvLat = (TextView) view.findViewById(R.id.tvLatitude);
TextView tvLon = (TextView) view.findViewById(R.id.tvLongitude);
String stopName = cursor.getString(cursor.getColumnIndexOrThrow("stop_name"));
String stopLat = cursor.getString(cursor.getColumnIndexOrThrow("stop_lat"));
String stopLon = cursor.getString(cursor.getColumnIndexOrThrow("stop_lon"));
String _id = cursor.getString(cursor.getColumnIndexOrThrow("_id"));
// Set textview with text from cursor
tvStopName.setText(stopName);
tvLat.setText(stopLat);
tvLon.setText(stopLon);
}
}
getAllStops()方法和getStopTimes()方法工作正常。它们与getAllLocations()方法的活动不同。
非常感谢任何帮助。
如果您需要更多信息,请与我们联系。