2009-09-27 9 views
42

पर एक संदर्भ प्राप्त करने का प्रयास मैंने मई में [एंड्रॉइड डेवलपर्स] Google समूह पर this पोस्ट किया। मैंने कभी वापस नहीं सुना और समस्या का पुन: उत्पन्न करने में सक्षम नहीं था जब तक कि मेरे छात्रों में से एक ने पिछले हफ्ते नहीं किया। मैंने सोचा कि मैं इसे यहां पोस्ट करूंगा और देख सकता हूं कि यह किसी के लिए घंटी बज रहा है या नहीं।अपवाद: एक करीबी SQLiteClosable

static Cursor getAll(SQLiteDatabase db, String orderBy) { 
     return(db.rawQuery("SELECT * FROM restaurants "+orderBy, null)); 

} 

जब मैंने इसे चलाने के लिए, कई मायनों में, मैं इस मिल:

05-01 14:45:05.849: ERROR/AndroidRuntime(1145): 
java.lang.IllegalStateException: attempt to acquire a reference on a 
close SQLiteClosable 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:31) 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
android.database.sqlite.SQLiteProgram.<init>(SQLiteProgram.java:56) 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
android.database.sqlite.SQLiteQuery.<init>(SQLiteQuery.java:49) 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:49) 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1118) 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
android.database.sqlite.SQLiteDatabase.rawQuery(SQLiteDatabase.java:1092) 
05-01 14:45:05.849: ERROR/AndroidRuntime(1145):  at 
apt.tutorial.Restaurant.getAll(Restaurant.java:14) 

यह मेरे लिए कोई मतलब नहीं है

मेरी कोड नमूने में से एक में, मैं निम्नलिखित तरीके होते है। डेटाबेस निश्चित रूप से खुला है। SQLiteClosableSQLiteQuerySQLiteQueryDriver द्वारा बनाई गई है, और मैं कोई सबूत नहीं है एक वस्तु पूल या कुछ और यहाँ चल रहा है कि कैसे एक 'नई' SQLiteClosable पहले से ही बंद कर दिया है समझा सकती है कि है कि वहाँ देख । तथ्य यह है कि यह स्पोरैडिक है (जिसका मतलब है कि यूआई ऑपरेशंस कभी-कभी अपवाद को ट्रिगर करता है, लेकिन हमेशा नहीं) कुछ प्रकार के पूल, रेस हालत, या कुछ ... का सुझाव देता है लेकिन मुझे यकीन नहीं है कि कहां है।

विचार?

धन्यवाद!

अद्यतन: प्रश्न में कोड मेरी Android Programming Tutorials किताब से बाहर LunchList ट्यूटोरियल से है। यह थोड़ा सा फैल गया है और सीधे एसओ में पोस्ट करने के लिए बहुत उपयुक्त नहीं है। यदि आप इसे देखना चाहते हैं तो आप उपरोक्त लिंक से उस पुस्तक के लिए कोड डाउनलोड कर सकते हैं। मुझे याद नहीं है कि उस समय ट्यूटोरियल का कौन सा संस्करण काम कर रहा था, हालांकि यह ट्यूटोरियल 12-ट्यूटोरियल 16 रेंज में था। मैं ज्यादातर किसी ऐसे व्यक्ति को चलाने की उम्मीद कर रहा था जिसने इस समस्या से पहले यात्रा की थी और संभावित अपराधी था। मैं काफी हद तक निश्चित हूं कि मेरा डेटाबेस खुला है। एक बार फिर धन्यवाद!

+0

क्या आपने इस पर कोई प्रगति की है? –

+0

अद्यतन देखें जो मैंने अभी मूल क्वेरी में जोड़ा है। यह इतनी दुर्लभ घटना है कि मैं बहुत चिंतित नहीं हूं; मैं बस किसी ऐसे व्यक्ति की उम्मीद कर रहा था जिसने समस्या को देखने से पहले समस्या थी। धन्यवाद! – CommonsWare

+0

हां, यह मेरे लिए भी बहुत ही कम होता है। फिर भी मैं कम से कम इसके लिए एक बग रिपोर्ट खोजने की उम्मीद करता, लेकिन मैंने नहीं किया। –

उत्तर

50

इसने मुझे सबसे लंबे समय तक पागल कर दिया। मैंने जो समाधान पाया है वह काफी सरल है: SQLiteDatabase ऑब्जेक्ट्स के संदर्भ न रखें। इसके बजाय, SQLiteOpenHelper का उपयोग करें और हर बार आपको आवश्यकता होने पर getWritableDatabase() पर कॉल करें।

सार्वजनिक सिंक्रनाइज़ SQLiteDatabase getWritableDatabase()

बनाएं और/या एक डेटाबेस है कि पढ़ने और लिखने के लिए इस्तेमाल किया जाएगा खोलें: डॉक्स से। सफलतापूर्वक खोला गया, डेटाबेस कैश किया गया है, इसलिए जब भी आपको डेटाबेस में लिखने की आवश्यकता होती है तो आप इस विधि को कॉल कर सकते हैं।

जवाब सही वहाँ पूरे समय था।

+1

हम्मम्म ... यह बहुत दिलचस्प है। ऐसा लगता है कि आप डेटाबेस को बंद करने के लिए SQLiteOpenHelper पर 'क्लोज़() 'को कॉल कर सकते हैं। मुझे इसके साथ प्रयोग करना होगा। बहुत धन्यवाद! – CommonsWare

+0

आपका बहुत स्वागत है! सवाल पूछने के लिए धन्यवाद; इससे मुझे समाधान पता लगाने में मदद मिली। –

+0

इसे काफी नहीं मिला। क्या आप एक और विस्तृत उदाहरण पोस्ट कर सकते हैं? – Codevalley

1

मुझे कुछ दिनों के लिए एक ही समस्या थी, और मेरा समाधान डेटाबेस क्वेरी के बाद मेरी क्वेरी और बंद() विधि से ठीक पहले() विधि डालना था। ऐसा कुछ दिखता है।

open(); 
Cursor cur=db.query(DATABASE_TABLE_CON, null, null, null, null, null, " name ASC"); 
close(); 
return cur; 

यह ठीक काम करता है, लेकिन मैं संसाधन लागत के लिए चिंतित हूं। मुझे यकीन नहीं है कि मैं किसी भी कार्रवाई से पहले इस उद्घाटन और समापन डेटाबेस के साथ अधिक संसाधन खर्च कर रहा हूं।

1

मुझे पहले से ही Jarett's advice का पालन करने के बावजूद एक ही समस्या का सामना करना पड़ रहा है।मेरे मामले में समस्या अभिविन्यास परिवर्तनों पर काफी नियमित रूप से हो रही है। मैंने पाया है कि, किसी कारण से मुझे अभी तक नीचे नहीं मिला है, मेरा कोड दो समान, बहुत अधिक असीमित AsyncTasks को अभिविन्यास परिवर्तन पर उत्पन्न करता है (जैसा कि गतिविधि सामान्य रूप से प्रारंभ होने पर केवल एक के विपरीत होती है)। ये कार्य एक ही समय में एक ही डेटाबेस क्वेरी को अलग-अलग धागे से करते हैं।

यह अपवाद (या कभी-कभी कुछ अन्य SQLiteException) परिणाम है। तो ऐसा लगता है कि यह संदेश समवर्ती समस्याओं का एक लक्षण हो सकता है, भले ही यह आवश्यक रूप से यहां पोस्ट की गई मूल समस्या की जड़ नहीं है।

+0

जब स्क्रीन अभिविन्यास बदलता है तो पूरी नई गतिविधि बनाई जाती है। यदि आप गतिविधि के ऑनक्रेट() विधि में अपना AsyncTasks प्रारंभ कर रहे हैं, तो दो बनाए जाएंगे। –

+0

यदि आप 'SQLiteOpenHelper' को सही तरीके से विस्तारित कर रहे हैं और'DDestroy()' में अपना डेटाबेस बंद कर रहे हैं, तो आपको डेटाबेस को संशोधित करने के लिए समवर्ती कॉल के साथ कोई समस्या नहीं होनी चाहिए। –

8

कुछ शर्तों के तहत SQLiteDatabase स्वचालित रूप से बंद हो जाता है।

http://darutk-oboegaki.blogspot.com/2011/03/sqlitedatabase-is-closed-automatically.html

getCount() और onMove() कर्सर के तरीकों SQLiteQuery का उपयोग कर एक वास्तविक क्वेरी ट्रिगर। सभी आवश्यक डेटा प्राप्त होने के बाद, SQLiteQuery SQLiteDatabase इंस्टेंस की संदर्भ गणना को कम करता है। जब संदर्भ गणना 0 तक पहुंच जाती है, तो डेटाबेस बंद हो जाता है।

ध्यान दें कि क्वेरी को असीमित रूप से निष्पादित किया जा सकता है और ऐसे मामले में, getCount() वापस लौटा सकता है यदि SQLiteQuery डेटा तैयार करने से पहले इसे कॉल किया जाता है।

+0

इस जानकारी के लिए बहुत बहुत धन्यवाद! मुझे नहीं पता था कि डीबी getCount() को कॉल करके बंद कर सकता है। – danh32

संबंधित मुद्दे