1. 程式人生 > >Error處理:java.lang.IllegalStateException: databases already closed

Error處理:java.lang.IllegalStateException: databases already closed

Android Error處理:java.lang.IllegalStateException: databases  already closed

今天匯入一個基於Android 2.x版本SDK專案,執行的時候一直出錯,錯誤如下:

11-18 16:58:56.595:E/AndroidRuntime(22991): java.lang.RuntimeException: Unable to start [email protected] with Intent {act=xxx.xxx.xxx.APP_SERVICE (has extras) }: java.lang.IllegalStateException:database /data/data/xxx.xxx.xxx/databases/xxx.db (conn# 0) already closed


判斷可能是資料庫操作部分出了問題,資料庫操作部分檔案程式碼DBHelper.java如下:
package org.yousee.utils;


import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
/**
 * 儲存記錄的資料庫
 */
public class DBHelper extends SQLiteOpenHelper {
	private Cursor c = null;
	private static final String CREATE_TAB = "create table "
		+ "music(_id integer primary key autoincrement,music_id integer,clicks integer," + "latest text)";
	private static final String TAB_NAME = "list";
	private SQLiteDatabase db = null;
	public DBHelper(Context context, String name, CursorFactory factory,int version) {
		super(context, name, factory, version);
	}

	@Override
	public void onCreate(SQLiteDatabase db) {
		this.db = db;
		db.execSQL(CREATE_TAB);
	}
	
	public void insert(ContentValues values){
		SQLiteDatabase db = this.getWritableDatabase();
		db.insert(TAB_NAME, null, values);
		db.close();//應改為this.close()
	}

	public void update(ContentValues values,int id){
		SQLiteDatabase db = this.getWritableDatabase();
		db.update(TAB_NAME, values, "music_id="+id, null);
		db.close();//應改為this.close()

	}
	
	public void delete(int id){
		if (db == null){
			db = getWritableDatabase();
		}
		db.delete(TAB_NAME, "music_id=?", new String[]{String.valueOf(id)});
	}
	
	public Cursor query(int id){
		SQLiteDatabase db = getReadableDatabase();
		c = db.query(TAB_NAME, null, "music_id=?", new String[]{String.valueOf(id)}, null, null, null);
		db.close();//應改為this.close()

		return c;
	}
	
	public Cursor queryByClicks(){//按點選量查詢
		SQLiteDatabase db = getReadableDatabase();
		c = db.query(TAB_NAME, null, null, null, null, null, "clicks desc");
		return c;
	}
	
	public Cursor queryRecently(){//按時間降序查詢
		SQLiteDatabase db = getReadableDatabase();
		c = db.query(TAB_NAME, null, null, null, null, null, "latest desc");
		return c;
	}
	
	public void close(){
		if (db != null){
			db.close();//應改為this.close()

			db=null;
		}
		if (c!=null){
			c.close();
			c=null;
		}
	}
	
	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

	}

}
經過 分析發現是關閉資料庫時直接呼叫了SQLiteDatabase.close()方法。

出錯的具體原因為:

如果呼叫SQLiteDatabase.close()代替SQLiteOpenHelper.close()。那麼SQLiteOpenHelper就不知道通過helper獲取的DB是否是關閉的(getReadableDatabase或getWritableDatabase)。

總結:

1、SQLiteOpenHelper.close()是非同步的,而SQLiteDatabase.close()不是。

2、在使用安卓提供的SQLiteOpenHelper時,通過getReadableDatabase或

getWritableDatabase獲得的其實是同一個物件,唯一的卻別就是如果你的硬碟不足了,那麼你就不能在呼叫getWritableDatabase,只能呼叫getReadableDatabase。

3、使用Android提供的資料庫介面進行資料庫操作的時候一定要遵循Andoid的規則。在多執行緒中要注意,所以養成好的面向物件的習慣,呼叫helper的close方法關閉資料庫。(誰提供的資料,就呼叫誰的方法來操作資料)

網上還看到有類似的問題:

http://androiddev.orkitra.com/?p=30756

http://stackoverflow.com/questions/6535908/android-sqlite-sqliteopenhelper-error-illegalstateexception-db-already-clo

相關推薦

Error處理java.lang.IllegalStateException: databases already closed

Android Error處理:java.lang.IllegalStateException: databases  already closed 今天匯入一個基於Android 2.x版本SDK專案,執行的時候一直出錯,錯誤如下: 11-18 16:58:56.59

StickyListHeadersListView——Android9.0崩潰java.lang.IllegalStateException 處理非空狀態的父類

記錄StickyListHeadersListView適配Android9.0報:java.lang.IllegalStateException :處理非空狀態的父類未 在android.view.ViewGroup的android.view.View.dispatchSaveInstan

java.lang.IllegalStateException: Fragment already added異常的處理

先判斷是否有fragment,如果fragment不為null,則判斷是都新增進去了,如果新增過直接展示不要重複建立 StaticFragment staticFragment = new StaticFragment(); if (staticFragment != null) { i

檔案下載java.lang.IllegalStateException: getOutputStream() has already been called for this response

1.報錯資訊 一月 24, 2018 10:23:47 下午 org.apache.catalina.core.ApplicationDispatcher invoke 嚴重: Servlet.service() for servlet jsp threw

解決kylin報錯java.lang.IllegalStateException

util bstr map dex apach default current con str 一個kylin build job執行到第三步Extract Fact Table Distinct Columns時報錯: 2017-05-24 20:04:07,930

專案啟動時報錯--報錯資訊為java.lang.IllegalStateException

專案啟動時報錯資訊:java.lang.IllegalStateException:BeanFactory not initialized or already closed -call ‘refresh’ before accessing beans via the Applocati

Druid異常處理java.lang.RuntimeException: No buckets?? seems there is no data to index.

2018-09-16T15:10:53,695 ERROR [task-runner-0-priority-0] io.druid.indexing.overlord.ThreadPoolTaskRunner - Exception while running task[HadoopIndexT

java.lang.IllegalStateException: commit already called

今天遇到一個 bug ,特來做一下記錄; 描述:我寫了 一份封裝的 Fragment 來回切換,但是顯示不出來;懷疑是 Fragment 在呼叫 show() 方法時也應該新增 commitAllowingStateLoss() 提交事務的方法,於是呼叫該方法後。便出現了異常。 異

IDEA 啟動報錯java.lang.IllegalStateException: failed to create a child event loop 問題解決

遇到的問題 昨天電腦自動更新了,今天死活啟動不了專案,看到idea的提示是: idea日誌如下 根據提示說 檢視idea的啟動日誌: 2018-11-20 17:35:42,010 [ 46737] INFO - plication.impl.Applicat

Spring Cloud RestTemplate報錯java.lang.IllegalStateException: No instances available for

java.lang.IllegalStateException: No instances available for localhost     原:restTemplate.getForObject( uri+"/user/getname",User.clas

錯誤處理java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilter

部署專案時,啟動Tomcat一直出錯:java.lang.NoSuchMethodException: org.apache.catalina.deploy.WebXml addFilterSEVERE: End event threw exception java.lang

關於 java.lang.IllegalStateException: Fragment already added 解決方式

前言 最近發現專案中出現這個bug,很頻繁。網上查找了幾種解決方案,效果不是太理想,現就將使用修改方案一一列出來 背景 專案底部四個tab頁面切換導致,tab切換方案是,將四個Fragment新增到一個Activity中進行管理動態hidden(),show()

Caused by java.lang.IllegalStateException

報錯如下: 嚴重: Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener

使用Fragment時出現 java.lang.IllegalStateException: Fragment already active

      異常出現的狀況:在使用Fragment的setArguments(Bundle args)傳遞引數的後,在切換Fragment時出現:java.lang.IllegalStateException: Fragment already activeat andro

java.lang.IllegalStateException: Fragment already added問題

在通過fragmentmanager管理fragment棧的時候,出現了java.lang.IllegalStateException: Fragment already added的錯誤,導致Ema

java.lang.IllegalStateException異常產生的原因及解決辦法

錯誤型別大致為以下幾種: java.lang.IllegalStateException:Cannot forward a response that is already committed IllegalStateExce

java.lang.IllegalStateException: Already using output stream分析及處理辦法

錯誤型別大致為以下幾種:java.lang.IllegalStateException:Cannot   forward   a   response   that   is   already   committed IllegalStateException:resp

排查sqoop報錯Error running child : java.lang.OutOfMemoryError: Java heap space

date 行數 content sin mapper native reader exti 占用 報錯棧: 2017-06-16 19:50:51,002 INFO [main] org.apache.hadoop.mapred.MapTask: Processing

java.lang.IllegalStateException: The specified child already has a parent.解決方案

公司的老專案,裡面使用的viewpager,最近測試反饋說閃退了,翻到日誌看到報如下錯誤java.lang.IllegalStateException: The specified child already has a parent.然後就找度娘,果不其然,度娘沒有讓我失望,找到了解決方法