IllegalStateException异常 - 支持LoaderManager与Autocomp

2019-07-31 01:42发布

一个好处我想用CursorLoaders和Loadermanagers是,你并不需要手动管理光标的生命周期。 所以我用一个loadermanager到适配器结合使用支持包的AutoCompleteTextView。

它的工作原理相当不错,除了它随意抛出一个错误说“IllegalStateException异常 - 尝试重新打开已关闭的对象”。 想必是不应该,如果我们使用装载机经理发生?

下面的代码:

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


    }


}

这里的错误堆栈:

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)

什么任何想法可能是错误的?

Answer 1:

OnLoadFinished似乎得到了死光标有时也被称为 - 如果你把一个测试为isClosed()你获得通过光标,你会发现它是一个在(一些大的数字)尝试关闭。

不幸的是,“标准”的代码放在OnLoadFinished立即做的适配器上changeCursor()的,那么,接踵而来的是一片混乱,stackdumps,瘟疫等。

我的解决方案并不比你的try / catch漂亮..忽略虚假OnLoadFinished和风险最终用户得到一个空白的UI。



文章来源: IllegalStateException - Support LoaderManager with AutocompleteTextView