IllegalStateException - 使用 AutocompleteTextView 支持 LoaderManager [英] IllegalStateException - Support LoaderManager with AutocompleteTextView

查看:29
本文介绍了IllegalStateException - 使用 AutocompleteTextView 支持 LoaderManager的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为使用 CursorLoaders 和 Loadermanagers 的好处之一是您无需手动管理游标的生命周期.所以我使用了一个 loadermanager 将一个适配器绑定到一个使用支持包的 AutoCompleteTextView.

One of the benefits I thought of using CursorLoaders and Loadermanagers was that you didn't need to manually manage the lifecycle of the cursor. So I used a loadermanager to bind an adapter to an AutoCompleteTextView using the support package.

它工作得很好,只是它随机抛出一个错误,说IllegalStateException - 尝试重新打开一个已经关闭的对象".如果我们使用加载器管理器,那肯定不会发生这种情况吗?

It works quite well except that it randomly throws an error saying "IllegalStateException - attempt to re-open an already closed object". Surely that's not supposed to happen if we're using the loader manager?

代码如下:

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)

有什么可能出问题的想法吗?

Any ideas on what could be wrong?

推荐答案

OnLoadFinished 有时似乎被调用并带有死游标 - 如果您对游标进行 isClosed() 测试,您会通过您会发现它已关闭一次(一些大的)尝试.

OnLoadFinished seems to get called sometimes with a dead cursor - if you put a test for isClosed() on the cursor you get passed you'll find it's closed in one in (some large number) attempts.

不幸的是,放在 OnLoadFinished 中的标准"代码会立即在适配器上执行 changeCursor(),然后是混乱、堆栈转储、瘟疫等.

Unfortunately the 'standard' code to put in OnLoadFinished immediately does a changeCursor() on the adapter and, well, what follows is chaos, stackdumps, pestilence, etc.

我的解决方案并不比您的 try/catch 更漂亮.. 忽略虚假的 OnLoadFinished 并冒最终用户获得空白 UI 的风险.

My solution isn't any prettier than your try/catch.. ignore the bogus OnLoadFinished and risk the end user getting a blank UI.

这篇关于IllegalStateException - 使用 AutocompleteTextView 支持 LoaderManager的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆