2013-07-07 19 views
4

我在關閉應用程序或讓手機與打開的應用程序一起睡時收到此錯誤消息。沒有事先關閉遊標()在ListFragment中結束()

當我讓手機進入睡眠狀態時,我收到了30條到61條此錯誤消息的日誌條目。在加載ListFragment之前記錄錯誤。我懷疑片段被加載,但在片段的信息條目之前記錄了錯誤。

當我關閉應用程序時,我只收到1條在onLoaderReset()調用後記錄的錯誤。在關閉應用程序之前關閉數據庫,這似乎有所幫助。

該應用程序的工作原理,但我擔心它會失敗,一旦運行在各種手機上。

我不顯式控制除onLoaderReset()中的adapter.swapCursor(null)之外的遊標。

我很欣賞關於如何解決此錯誤的任何想法。

感謝

public class ChildList extends ListFragment implements 
    LoaderManager.LoaderCallbacks<Cursor>, DatabaseConstants, GoodiList { 

private final String TAG = "ChildList"; 

// database columns that we will retreive 
final String[] PROJECTION = new String[] { CHILD_ID_COLUMN, 
     CHILD_NAME_COLUMN }; 

// selects all 
final String SELECTION = null; 

SimpleCursorAdapter adapter = null; 

private ListParent parentActivity; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    Log.e(TAG, "on Create"); 
    String[] fromColumns = { CHILD_NAME_COLUMN, CHILD_ID_COLUMN }; 

    int[] toViews = { R.id.name_column, R.id.id_column }; 

    adapter=new SimpleCursorAdapter(
      getActivity(), 
      R.layout.child_list_entry, 
      null, 
      fromColumns, 
      toViews, 
      0 
      ); 

    setListAdapter(adapter); 

    getLoaderManager().initLoader(0, null, this); 

    Log.i(TAG, "finished on Create"); 
} 


public void onActivityCreated(Bundle savedInstanceState) { 
    super.onActivityCreated(savedInstanceState); 

    LongClickListener longClickListener = new LongClickListener(); 

    getListView().setOnItemLongClickListener(longClickListener); 
} 

@Override 
public void setListAdapter(ListAdapter adapter) { 
    super.setListAdapter(adapter); 
} 

@Override 
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { 

    Log.v(TAG, "starting on create loader"); 

    Uri CHILD_URI = ChildContentProvider.CONTENT_URI; 

    CursorLoader cursorLoader = new CursorLoader(getActivity(), CHILD_URI, 
      PROJECTION, SELECTION, null, null); 

    Log.v(TAG, "finished on create loader"); 

    return cursorLoader; 
} 

@Override 
public void onLoadFinished(Loader<Cursor> arg0, Cursor newCursor) { 
    adapter.swapCursor(newCursor); 

    if (newCursor != null) { 
     int rowCount = newCursor.getCount(); 

     Log.v(TAG, "--- onLoadFinished: got " + rowCount + " children"); 
    } 
} 

/** 
* this used to delete. However, we need it to select usually. Now delete is 
* done by long click. 
*/ 
@Override 
public void onListItemClick(ListView l, View v, int position, long id) { 
    super.onListItemClick(l, v, position, id); 

    // delete child - remove child from list and database 
    Object item = l.getItemAtPosition(position); 

    Cursor cursor = (Cursor) item; 

    int nameCol = cursor.getColumnIndex(CHILD_NAME_COLUMN); 
    int idCol = cursor.getColumnIndex(CHILD_ID_COLUMN); 

    final String name = cursor.getString(nameCol); 

    final int childId = cursor.getInt(idCol); 

    Log.i(TAG, "selected " + name + " id: " + childId + " at position " 
      + position); 

    cursor.close(); 

    parentActivity.listItemSelected(this, position, childId); 

} 

/** 
* Forces cursor to requery database and list to be update. Used when a new 
* child is entered in parent activity's EditText field. 
*/ 
public void notifyDataChanged() { 

    Log.i(TAG, "told adapter that data changed"); 

    getLoaderManager().restartLoader(0, null, this); 

    adapter.notifyDataSetChanged(); 
} 

/** tell adapter that cursor is no longer valid*/ 
@Override 
public void onLoaderReset(Loader<Cursor> arg0) { 
Log.i(TAG,"---- onLoaderReset -----"); 

adapter.swapCursor(null); 

} 

@Override 
public void onAttach(Activity activity) { 
    super.onAttach(activity); 

    parentActivity = (ListParent) activity; 

    parentActivity.setList(this); 

} 
+0

這不是錯誤味精,它是警告......! –

+0

雖然應該有一些避免它的方法。 – astuter

+0

@ jeff-of-brooklyn你是否設法找到答案?我現在正在努力解決同樣的問題。 –

回答

0

我有同樣的問題,我採取的文檔仔細看解決它。

根據該文檔,http://developer.android.com/reference/android/widget/CursorAdapter.html#swapCursor(android.database.Cursor)

swapCursor(Cursor data)返回原始未封閉的光標的方法。如果新遊標與舊遊標相同或者沒有舊遊標,則返回null。

通過從

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    adapter.swapCursor(data); 
} 

改變我的代碼

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor data) { 
    Cursor cursor = adapter.swapCursor(data); 
    if (cursor != null) { 
     cursor.close(); 
    } 
} 

我停止這些警告出現。

注意:您也應該對onLoaderReset()方法也這樣做。即使你做adapter.swapCursor(null),它也會返回舊的光標。

0

您應該使用的changeCursor(Cursor cursor)代替swapCursor(Cursor cursor)

如果你看一下documentation,你會看到,它還會關閉舊的光標。