2017-08-07 30 views
0

我正在嘗試通過AsyncTask中的聯繫人簿中的號碼查找聯繫人姓名。有時我會遇到以下錯誤,我認爲這會導致應用程序崩潰。請任何幫助。應用程序未關閉遊標或數據庫對象android

logcat的

08-05 09:00:49.627 24988-27371/com.fake.fake E/CursorLeakDetecter: PossibleCursorLeak:content://com.android.contacts/phone_lookup/%2B923310433708,QueryCounter:5 
android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here 
    at android.content.ContentResolver.query(ContentResolver.java:323) 
    at com.fake.fake.GV.getContactName(GV.java:177) 
    at com.fake.fake.MySQLiteHelper.GetNumbers(MySQLiteHelper.java:361) 
    at com.fake.fake.MainActivity$taskLoadContacts.doInBackground(MainActivity.java:930) 
    at com.fake.fake.MainActivity$taskLoadContacts.doInBackground(MainActivity.java:921) 
    at android.os.AsyncTask$2.call(AsyncTask.java:264) 
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
    at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
    at java.lang.Thread.run(Thread.java:856) 

從數據庫中檢索聯繫人號碼。

public ArrayList<MyMessageDetails> GetNumbers(String query) { 
     ArrayList<MyMessageDetails> numbers = new ArrayList<MyMessageDetails>(); 
     Cursor cursor = db.rawQuery(query, null); 
     if (cursor != null && cursor.moveToFirst()) { 
      do { 
       MyMessageDetails item = new MyMessageDetails(); 
       item.setNumber(cursor.getString(0)); 
       String name = GV.getContactName(item.getNumber());  
       if (name == null) { 
        name = item.getNumber(); 
       } 
       item.setName(name); 
       item.setTime(cursor.getString(3)); 
       numbers.add(item); 
      } while (cursor.moveToNext()); 

     } 
     return numbers; 
    } 

檢索聯繫人姓名。

public static String getContactName(String phoneNumber) { 
     if (phoneNumber != null) { 
      ContentResolver cr = ApplicationContextProvider.getContext().getContentResolver(); 
      Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber)); 
      Cursor cursor = cr.query(uri, new String[]{ContactsContract.PhoneLookup.DISPLAY_NAME}, null, null, null); 
      if (cursor == null) { 
       return ""; 
      } 
      String contactName = null; 
      if (cursor.moveToFirst()) { 
       contactName = cursor.getString(cursor.getColumnIndex(ContactsContract.PhoneLookup.DISPLAY_NAME)); 
      } 

      if (cursor != null && !cursor.isClosed()) { 
       cursor.close(); 
      } 
      return contactName; 
     } 

     return phoneNumber; 
    } 
+0

請參閱:https://stackoverflow.com/questions/ 4991179/application-did-not-close-the-cursor-or-database-object-that-opened-here-rq = 1 –

+0

感謝您的鏈接,但錯誤來自「getContactName」而不是來自GetNumbers。 – user934820

回答

0

所以我在這裏看到的幾個問題。

首先,請始終圍繞try catch finally塊中的查詢執行環節,並關閉finally塊中的所有遊標和數據庫操作。所以這兩個你的方法。

我認爲你在做什麼錯在這裏首先調用GetNumbers()方法,然後getContactName()。現在你不要在代碼中關閉GetNumbers()中的db,因此在那之後你嘗試在db上做的任何操作都會給出這個錯誤,因此出現錯誤getContactName()

+0

謝謝你的「試試最後」的建議。我想讓我的數據庫保持打開狀態,這就是爲什麼它沒有關閉。我是否也應該在finally塊中關閉遊標? – user934820

+1

是的,你應該在finally塊中做到這一點。最好關閉數據庫並在需要時再次打開。或者您可以在該方法中執行與該部分數據相關的所有數據庫操作並關閉它。 –

2

使用Cursor#close()完成讀取數據後。例如:

Cursor cursor = ... 
try { 
    // fetch whatever you need here 
} finally { 
    cursor.close(); 
} 
+0

謝謝讓我檢查。 – user934820

相關問題