6

Một trong những lợi ích mà tôi nghĩ đến khi sử dụng CursorLoaders và Loadermanagers là bạn không cần phải quản lý vòng đời của con trỏ theo cách thủ công. Vì vậy, tôi đã sử dụng loadermanager để liên kết một bộ điều hợp với một AutoCompleteTextView bằng cách sử dụng gói hỗ trợ.IllegalStateException - Hỗ trợ LoaderManager với AutocompleteTextView

Nó hoạt động khá tốt ngoại trừ việc nó ngẫu nhiên ném một lỗi nói "IllegalStateException - cố gắng mở lại một đối tượng đã đóng". Chắc chắn đó không phải là điều xảy ra nếu chúng ta đang sử dụng trình quản lý bộ nạp?

Dưới đây là các mã:

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); 


    } 


} 

Đây là lỗi stack:

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) 

Bất kỳ ý tưởng về những gì có thể xảy ra?

+1

Mặc dù tôi vẫn không có giải pháp, tôi vừa mở rộng AutoCompleteTextView, đã gặp lỗi trong onFilterComplete trong một vòng lặp try/catch xung quanh câu lệnh "super", bỏ qua nó và tiếp tục. Tôi không có ý tưởng tại sao nó xảy ra hoặc làm thế nào để xử lý nó. Đã giải quyết được sự cố. Lộn xộn mặc dù. Sẽ đánh giá cao một giải pháp thanh lịch hơn. –

+0

Tôi đang làm điều gì đó tương tự TẠI ĐÂY !! http://stackoverflow.com/questions/12854336/autocompletetextview-backed-by-cursorloader – toobsco42

+0

@BhagwadJalPark Tôi đã giải quyết vấn đề này như bạn có. Giải pháp được đề xuất bởi Tony (kiểm tra trạng thái đóng trong OnLoadFinished) không hoạt động đối với tôi. Dưới đây là lớp trình bao bọc mà tôi đã viết cho mỗi thông tin chi tiết của bạn: https://gist.github.com/esilverberg/5606551 – esilver

Trả lời

7

OnLoadFinished dường như được gọi đôi khi với một con trỏ chết - nếu bạn đặt một thử nghiệm cho isClosed() trên con trỏ bạn nhận được thông qua bạn sẽ tìm thấy nó đóng một trong một số (một số lượng lớn) cố gắng.

Đáng tiếc là mã 'tiêu chuẩn' để đưa vào OnLoadFinished ngay lập tức không một changeCursor() trên các adapter và, tốt, những gì sau là hỗn loạn, stackdumps, bệnh dịch hạch, vv

Giải pháp của tôi không được bất kỳ đẹp hơn thử/nắm bắt của bạn .. bỏ qua không có thật OnLoadFinished và có nguy cơ người dùng cuối nhận được một giao diện người dùng trống.

+1

Cảm ơn bạn đã xem mẩu tin đó. Đối với trường hợp cụ thể này, tôi đã bỏ hoàn toàn loadermanager/cursorloaer và thực hiện một cách khác để thực hiện điều này với setfilterqueryprovider. Nhưng giải pháp của bạn dường như là cách tốt nhất để đi. Có lẽ chúng tôi có thể gửi báo cáo lỗi ở đâu đó? –