6

CursorLoaders 및 Loadermanagers를 사용하여 생각한 이점 중 하나는 커서의 수명주기를 수동으로 관리 할 필요가 없다는 것입니다. 그래서 loadermanager를 사용하여 지원 패키지를 사용하여 AutoCompleteTextView에 어댑터를 바인딩했습니다.IllegalStateException - AutocompleteTextView가있는 LoaderManager

"IllegalStateException - 이미 닫힌 개체를 다시 열려고 시도했습니다."라는 오류를 임의로 throw합니다. 우리가 로더 관리자를 사용한다면 그것은 일어나지 않을 것입니다. 잘못 될 수 있는지에

08-16 22:21:23.244: E/AndroidRuntime(25475): java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, player_name FROM players WHERE (player_name LIKE ?)) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:33) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:82) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:164) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:147) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:178) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:162) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.support.v4.widget.CursorAdapter.getItem(CursorAdapter.java:213) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.widget.AutoCompleteTextView.buildImeCompletions(AutoCompleteTextView.java:1113) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1072) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.widget.AutoCompleteTextView.updateDropDownForFilter(AutoCompleteTextView.java:950) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.widget.AutoCompleteTextView.onFilterComplete(AutoCompleteTextView.java:932) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.widget.Filter$ResultsHandler.handleMessage(Filter.java:285) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.os.Handler.dispatchMessage(Handler.java:99) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.os.Looper.loop(Looper.java:137) 
08-16 22:21:23.244: E/AndroidRuntime(25475): at android.app.ActivityThread.main(ActivityThread.java:4507) 

어떤 아이디어 :

package com.bhagwad.tennis; 

import android.appwidget.AppWidgetManager; 
import android.content.Intent; 
import android.database.Cursor; 
import android.os.Bundle; 
import android.support.v4.app.FragmentActivity; 
import android.support.v4.app.LoaderManager.LoaderCallbacks; 
import android.support.v4.content.CursorLoader; 
import android.support.v4.content.Loader; 
import android.support.v4.widget.SimpleCursorAdapter; 
import android.support.v4.widget.SimpleCursorAdapter.CursorToStringConverter; 
import android.text.Editable; 
import android.text.TextWatcher; 
import android.view.View; 
import android.view.View.OnClickListener; 
import android.widget.AutoCompleteTextView; 
import android.widget.Button; 

import com.bhagwad.tennis.TennisSchedule.TennisScheduleColumns; 


public class WidgetConfiguration extends FragmentActivity implements OnClickListener, LoaderCallbacks<Cursor> { 

    Button mSaveWidget; 
    AutoCompleteTextView mPlayerName; 
    int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; 
    String mSelection =""; 
    SimpleCursorAdapter mAdapter; 

    public static String PREFS = "com.bhagwad.tennis.appwidget"; 
    public static final String PREFS_PREFIX_KEY = "prefix_"; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.widget_configuration); 

     mPlayerName = (AutoCompleteTextView) findViewById(R.id.edit_filter); 

     mPlayerName.addTextChangedListener(new TextWatcher() { 

      @Override 
      public void onTextChanged(CharSequence s, int start, int before, int count) { 

       if (!s.equals("")) 
        mSelection = s.toString(); 
       else 
        mSelection = ""; 

       getSupportLoaderManager().restartLoader(0, null, WidgetConfiguration.this); 



      } 

      @Override 
      public void beforeTextChanged(CharSequence s, int start, int count, 
        int after) { 
       // TODO Auto-generated method stub 

      } 

      @Override 
      public void afterTextChanged(Editable s) { 
       // TODO Auto-generated method stub 

      } 
     }); 

     // Set up the adapter 

     mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_1, null, new String[] {TennisScheduleColumns.PLAYER_NAME}, new int[] {android.R.id.text1}, 0); 
     mAdapter.setCursorToStringConverter(new CursorToStringConverter() { 

      @Override 
      public CharSequence convertToString(Cursor c) { 

       return c.getString(c.getColumnIndexOrThrow(TennisScheduleColumns.PLAYER_NAME)); 

      } 
     }); 

     mPlayerName.setAdapter(mAdapter); 

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

    } 


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

     return new CursorLoader(this, TennisScheduleColumns.CONTENT_URI_PLAYERS, new String[] {TennisScheduleColumns._ID, TennisScheduleColumns.PLAYER_NAME}, TennisScheduleColumns.PLAYER_NAME + " LIKE ?", new String[] {"%"+mSelection+"%"}, null); 

    } 


    @Override 
    public void onLoaderReset(Loader<Cursor> arg0) { 
     mAdapter.swapCursor(null); 

    } 

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


    } 


} 

다음 오류 스택입니다 : 여기

코드인가?

+1

아직 해결 방법이 없지만 AutoCompleteTextView를 확장하고 "super"문을 둘러싼 try/catch 루프에서 onFilterComplete 오류를 포착하고 무시하고 무시했습니다. 왜 그것이 발생했는지 또는 어떻게 처리해야하는지 전혀 모른다. 문제 해결됨. 그래도 지저분 해. 좀 더 우아한 해결책을 고맙게 생각합니다. –

+0

나는 비슷한 것을하고있다 !! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42

+0

@BhagwadJalPark 나는이 문제를 해결했습니다. Tony가 제안한 솔루션 (OnLoadFinished에서 닫힌 상태 확인)이 나에게 효과가 없었습니다. 다음은 귀하의 통찰력에 따라 작성한 래퍼 클래스입니다. https://gist.github.com/esilverberg/5606551 – esilver

답변

7

OnLoadFinished가 가끔씩 불필요한 커서와 함께 호출되는 것 같습니다. 커서에 isClosed()에 대한 테스트를 수행하면 전달 된 일부 (다수의) 시도가 닫힙니다.

불행하게도 '표준'코드

내 솔루션은보다 예뻐 상기 어댑터 changeCursor()와, 음, 다음 무엇 혼란, stackdumps, 전염병 등을지지 않습니다 즉시 OnLoadFinished에 넣어 try/catch .. 가짜 OnLoadFinished를 무시하고 최종 사용자가 빈 UI를받을 위험이 있습니다.

+1

그 맛있는 음식에 감사드립니다. 이 특별한 경우에는 loadermanager/cursorloaer를 완전히 덤프하고 setfilterqueryprovider를 사용하여이 작업을 수행하는 다른 방법을 구현했습니다. 하지만 당신의 솔루션이 가장 좋은 방법 인 것 같습니다. 아마도 어딘가에서 버그 리포트를 제출할 수 있습니까? –

관련 문제