我有一个SQLite数据库,用于存储我的Google地图的坐标。它工作正常但在我的logcat中我收到了这个错误:
01-25 14:36:24.338: E/SQLiteDatabase(12337): close() was never explicitly called on database '/data/data/com.example.androidbasic12/databases/android_api'
01-25 14:36:24.338: E/SQLiteDatabase(12337): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:2072)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1126)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:1083)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:1170)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:844)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:228)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:157)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:231)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at com.example.androidbasic12.library.DatabaseHandler.getLatLng(DatabaseHandler.java:153)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at com.example.androidbasic12.library.UserFunctions.getCoords(UserFunctions.java:124)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at com.example.androidbasic12.map.onCreate(map.java:61)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.Activity.performCreate(Activity.java:4470)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1052)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1931)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1992)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.ActivityThread.access$600(ActivityThread.java:127)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1158)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.os.Handler.dispatchMessage(Handler.java:99)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.os.Looper.loop(Looper.java:137)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at android.app.ActivityThread.main(ActivityThread.java:4511)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at java.lang.reflect.Method.invokeNative(Native Method)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at java.lang.reflect.Method.invoke(Method.java:511)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:980)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:747)
01-25 14:36:24.338: E/SQLiteDatabase(12337): at dalvik.system.NativeStart.main(Native Method)
01-25 14:36:24.338: E/System(12337): Uncaught exception thrown by finalizer
01-25 14:36:24.343: E/System(12337): java.lang.IllegalStateException: Don't have database lock!
01-25 14:36:24.343: E/System(12337): at android.database.sqlite.SQLiteDatabase.verifyLockOwner(SQLiteDatabase.java:2230)
01-25 14:36:24.343: E/System(12337): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2322)
01-25 14:36:24.343: E/System(12337): at android.database.sqlite.SQLiteDatabase$1.entryRemoved(SQLiteDatabase.java:2318)
01-25 14:36:24.343: E/System(12337): at android.util.LruCache.trimToSize(LruCache.java:197)
01-25 14:36:24.343: E/System(12337): at android.util.LruCache.evictAll(LruCache.java:285)
01-25 14:36:24.343: E/System(12337): at android.database.sqlite.SQLiteDatabase.deallocCachedSqlStatements(SQLiteDatabase.java:2283)
01-25 14:36:24.343: E/System(12337): at android.database.sqlite.SQLiteDatabase.closeClosable(SQLiteDatabase.java:1255)
01-25 14:36:24.343: E/System(12337): at android.database.sqlite.SQLiteDatabase.finalize(SQLiteDatabase.java:2043)
01-25 14:36:24.343: E/System(12337): at java.lang.Daemons$FinalizerDaemon.doFinalize(Daemons.java:185)
01-25 14:36:24.343: E/System(12337): at java.lang.Daemons$FinalizerDaemon.run(Daemons.java:168)
01-25 14:36:24.343: E/System(12337): at java.lang.Thread.run(Thread.java:856)
据我所知,在使用它之后我还没有关闭我的数据库连接,问题是错误点在哪里我似乎确实关闭了它。
userFunctions.class
public String getUsername(Context context, String uname) {
DatabaseHandler db = new DatabaseHandler(context);
Cursor cursor = db.getUsername();
cursor.moveToFirst();
if (cursor != null){
uname = cursor.getString(cursor.getColumnIndex("name"));
}
cursor.close();
db.close();
return uname;
}
/**
* Get lat and lng from TABLE_CARCOORDS
*/
public ArrayList<String> getCoords(Context context, String lat, String lng) {
DatabaseHandler db = new DatabaseHandler(context);
Cursor cursor = db.getLatLng();
if (cursor != null && cursor.moveToFirst()){
ArrayList<String> cordarr = new ArrayList<String>();
lat = cursor.getString(cursor.getColumnIndex("lat"));
lng = cursor.getString(cursor.getColumnIndex("lng"));
cordarr.add(lat);
cordarr.add(lng);
return cordarr;
}
cursor.close();
db.close();
return null;
}
databasehandler.class
public Cursor getUsername(){
SQLiteDatabase db = this.getReadableDatabase();
String query = ("SELECT * FROM " + TABLE_LOGIN + " WHERE name = " + KEY_NAME);
Cursor cursor = db.rawQuery(query, null);
return cursor;
}
public Cursor getLatLng(){
SQLiteDatabase db = this.getReadableDatabase();
String query = ("SELECT * FROM " + TABLE_CARCOORD + " WHERE name = " + CAR_KEY_NAME);
Cursor cursor = db.rawQuery(query, null);
return cursor;
}
最后,map.class
public class map extends FragmentActivity{
private static LatLng SYDNEY = new LatLng(-33.88,151.21);
public static LatLng sala = new LatLng(59.91602, 16.594108);
int travel = 0;
int MapTypeInt = 0;
private GoogleMap mMap;
GoogleMapOptions options = new GoogleMapOptions();
String username;
String Lat1;
String Lng1;
Double lat;
Double lng;
ProgressDialog dialog;
// JSON response node names
private static String KEY_SUCCESS = "success";
private static String KEY_ERROR = "error";
private static String KEY_NAME = "name";
private static String KEY_LAT = "lat";
private static String KEY_LNG = "lng";
String errorhandler = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.maps);
new getCord().execute();
setUpMapIfNeeded();
UserFunctions userFunc = new UserFunctions();
ArrayList<String> cordarr = new ArrayList<String>();
cordarr = userFunc.getCoords(getApplicationContext(), Lat1, Lng1);
if(cordarr != null && cordarr.size()> 1 ){
Log.d("LOG", "I got lat long");
Lat1 = cordarr.get(0);
Lng1 = cordarr.get(1);
lat = goDouble(Lat1);
lng = goDouble(Lng1);
LatLng sala = new LatLng(lat, lng);
mMap.addMarker(new MarkerOptions().position(sala).title("Coords: "
+ lat + ", "
+ lng));
} else {
Log.d("LOG", "no lat long found");
}
//Button that sends the user to Sala by default, and to Sydney if Sala
Button btnSyd = (Button) findViewById(R.id.btnSyd);
btnSyd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stu
if (travel == 0){
travelToSala();
travel = 1;
} else if (travel == 1) {
travelToSydney();
travel = 0;
}
}
});
//Button for setting map type to satellite if normal, to normal if satellite
final ImageButton changeBtn =(ImageButton) findViewById(R.id.changeBtn);
changeBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
changeMapType(changeBtn);
}
});
}
//method that changes maptype
private void changeMapType(ImageButton button){
if(MapTypeInt == 0){
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
button.setImageResource(R.drawable.normal_map);
MapTypeInt = 1;
} else if (MapTypeInt == 1) {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
button.setImageResource(R.drawable.satellite);
MapTypeInt = 0;
}
}
//Function that travels user to Sydney
private void travelToSydney(){
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 15));
Button btnSyd = (Button) findViewById(R.id.btnSyd);
btnSyd.setText("travel to Sala");
}
//Function that travels user to Sala
private void travelToSala(){
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(sala, 15));
Button btnSyd = (Button) findViewById(R.id.btnSyd);
btnSyd.setText("travel to Sydney!");
}
//Checks if map is setup, and if it isn't, set's up the map
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(sala, 15));
options.mapType(GoogleMap.MAP_TYPE_NORMAL)
.compassEnabled(true)
.rotateGesturesEnabled(true)
.tiltGesturesEnabled(true);
if(mMap != null){
//The map is veriefied
}
}
}
//method input string, output double
public Double goDouble(String Latlng) {
Double goDouble = Double.parseDouble(Latlng);
return goDouble;
}
class getCord extends AsyncTask<String, String, String>{
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
UserFunctions userFunction = new UserFunctions();
username = userFunction.getUsername(getApplicationContext(), "uname");
JSONObject json = userFunction.getCarcoord(username);
try {
if (json.getString(KEY_SUCCESS) != null){
String res = json.getString(KEY_SUCCESS);
if (Integer.parseInt(res)==1){
//Successfully found users car coordinates
DatabaseHandler db = new DatabaseHandler(getApplicationContext());
JSONObject json_coord = json.getJSONObject("user");
//clear previous entries in table "TABLE_COORD"
userFunction.resetCarcoord(getApplicationContext());
db.addCoord(json_coord.getString(KEY_NAME), json_coord.getString(KEY_LAT), json_coord.getString(KEY_LNG));
errorhandler = "2";
}
} else if(json.getString(KEY_ERROR) != null) {
String res = json.getString(KEY_ERROR);
if(Integer.parseInt(res) == 1){
//Some error in getting registration, should not happen though
errorhandler = "1";
}
}
}catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
dialog = ProgressDialog.show(map.this,
"Loading car coordinats", "Please wait ...", true, true);
super.onPreExecute();
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
if(errorhandler == "1"){
Toast toast = Toast.makeText(getApplicationContext(),
"User has not got car", Toast.LENGTH_LONG);
toast.show();
errorhandler = "";
} else if (errorhandler == "2" ) {
// Error in login
Toast toast = Toast.makeText(getApplicationContext(),
"Successfully got coords for car", Toast.LENGTH_LONG);
toast.show();
errorhandler = "";
}
dialog.cancel();
}
}
}
很抱歉,如果有很多不相关的代码!
答案 0 :(得分:0)
您必须关闭每个DatabaseHelper(在您的案例中为DatabaseHandler
)实例。
避免这样做的最好方法是只为整个应用程序使用一个DatabaseHandler。
这是它的相关代码,以实现上述目标:
public static DatabaseHandler sInstance;
public static synchronized DatabaseHandler getHandler(Context context) {
if (sInstance == null) {
sInstance = new DatabaseHandler(context);
}
return sInstance;
}