4

SimpleCursorAdapter をテストするのはこれが初めてです。ORMLiteで使いたいです。

残念ながら、私は常に StaleDataException を取得します:(

編集: adapter.swapCursor(c) が問題かどうかはわかりません。それを問題なく乗り越えました。問題は別の場所にあるようです /END EDIT

adapter.swapCursor(c)でエラーが発生しているようです。c が閉じています。これが問題のようです。どうすれば修正できますか?また、なぜ閉じているのですか? 注: エラーは、Einsatz1 sqllite テーブルにデータが含まれている場合にのみ発生します。テーブルが空の場合、すべてが完全に実行されます。

これは私の活動です:

public class UebersichtEinsaetze extends FragmentActivity implements LoaderManager.LoaderCallbacks<Cursor>
{
...

  public DatabaseHelper helper = null;

  @Override
  protected void onDestroy()
  {
    super.onDestroy();
    ((SimpleCursorAdapter) einsatzListView.getAdapter()).getCursor().close();
    helper.close();
    if (helper != null)
    {
      OpenHelperManager.releaseHelper();
      helper = null;
    }

  }

  private DatabaseHelper getHelper()
  {
    if (helper == null)
    {
      helper = OpenHelperManager.getHelper(this, DatabaseHelper.class);
    }
    return helper;
  }

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

    setContentView(R.layout.activity_ubersicht_einsaetze);
    einsatzListView = (ListView) findViewById(android.R.id.list);
    einsatzDatumTextView = (TextView) findViewById(R.id.tv_uebersicht_abdatum);
    fillData();
    getHelper();
  }

  private void fillData()
  {
    String[] from = new String[] { "_id" };
    int[] to = new int[] { R.id.view_list_einsatz_text_projnr };

    adapter = new SimpleCursorAdapter(this, R.layout.view_list_eintrag_einsatz, null, from, to, 0);
    getSupportLoaderManager().initLoader(0, null, this);
    einsatzListView.setAdapter(adapter);
  }

  @Override
  public Loader<Cursor> onCreateLoader(int id, Bundle args)
  {
    String[] projection = { "_id" };
    CursorLoader cursorLoader = new CursorLoader(this, test.CONTENT_URI, projection, null, null, null);
    return cursorLoader;
  }

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

  @Override
  public void onLoaderReset(Loader<Cursor> loader)
  {
    adapter.swapCursor(null);
  }
}

これは私のコンテンツプロバイダーです:

 private DatabaseHelper database;
  private RuntimeExceptionDao<Einsatz1, String> dao;

  // Used for the UriMacher
  private static final int EINSAETZE = 10;
  private static final int EINSATZ_ID = 20;

  private static final String AUTHORITY = "de.myapp.android";

  private static String BASE_PATH = "einsaetze";
  public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);

  public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE + "/einsaetze";
  public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE + "/einsatz";

  private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  static
  {
    sURIMatcher.addURI(AUTHORITY, BASE_PATH, EINSAETZE);
    sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", EINSATZ_ID);
  }

@Override
  public boolean onCreate()
  {
    database = new DatabaseHelper(getContext());
    this.dao = (RuntimeExceptionDao<Einsatz1, String>) database.getRTE(Einsatz1.class);
    return false;
  }

@Override
  public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
  {
    // ignore method parameters for now just to get it basically working

    QueryBuilder<Einsatz1, String> queryBuilder = this.dao.queryBuilder();

    Cursor cursor = null;
    CloseableIterator<Einsatz1> iterator = null;
    try
    {
      iterator = dao.iterator(queryBuilder.prepare());
      AndroidDatabaseResults results = (AndroidDatabaseResults) iterator.getRawResults();
      cursor = results.getRawCursor();
    }
    catch (SQLException e)
    {
      Log.e(getClass().getName(), "get cursor", e);
    }
    finally
    {
      iterator.closeQuietly();
    }

    // Make sure that potential listeners are getting notified
    cursor.setNotificationUri(getContext().getContentResolver(), uri);

    return cursor;
  }

ログキャット:

01-09 10:01:29.591: E/AndroidRuntime(3767): FATAL EXCEPTION: main
01-09 10:01:29.591: E/AndroidRuntime(3767): android.database.StaleDataException: Attempting to access a closed CursorWindow.Most probable cause: cursor is deactivated prior to calling this method.
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.database.CursorWrapper.getString(CursorWrapper.java:114)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.support.v4.widget.SimpleCursorAdapter.bindView(SimpleCursorAdapter.java:135)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.support.v4.widget.CursorAdapter.getView(CursorAdapter.java:256)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.AbsListView.obtainView(AbsListView.java:2267)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.ListView.measureHeightOfChildren(ListView.java:1244)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.ListView.onMeasure(ListView.java:1156)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.View.measure(View.java:15172)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.RelativeLayout.measureChild(RelativeLayout.java:602)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.RelativeLayout.onMeasure(RelativeLayout.java:415)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.View.measure(View.java:15172)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.View.measure(View.java:15172)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.LinearLayout.measureVertical(LinearLayout.java:833)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.LinearLayout.onMeasure(LinearLayout.java:574)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.View.measure(View.java:15172)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:4814)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2148)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.View.measure(View.java:15172)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:1848)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1100)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1273)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:998)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:4212)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:725)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.Choreographer.doCallbacks(Choreographer.java:555)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.Choreographer.doFrame(Choreographer.java:525)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:711)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.os.Handler.handleCallback(Handler.java:615)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.os.Handler.dispatchMessage(Handler.java:92)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.os.Looper.loop(Looper.java:137)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at android.app.ActivityThread.main(ActivityThread.java:4745)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at java.lang.reflect.Method.invokeNative(Native Method)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at java.lang.reflect.Method.invoke(Method.java:511)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
01-09 10:01:29.591: E/AndroidRuntime(3767):     at dalvik.system.NativeStart.main(Native Method)

小さなメモ (重要ではありませんが、誰かが情報を持っている場合...): adapter.swapCursor(c) の前にブレークポイントを設定すると、エラーが発生する前に停止しません。そのステートメントの前に挿入されたダミーの「int bla = 123」を実行するには、ブレークポイントを設定する必要があります。同様に、public Cursor query(...) メソッドの任意の場所にブレークポイントを設定すると、すべてがエラーなしで実行されますが (なんてこった...)、ブレークポイントで停止することはありません。

4

2 に答える 2

4

解決した

コメントアウト

iterator.closeQuietly();

私はコードを見つけましたが、これはここから来ました:

CursorAdapter で使用する ORMLite を使用した Android カーソル

……あてにしてはいけない。

コメントアウトがどのような悪影響をもたらす可能性があるかを確認する必要がありますが (誰かが知っている場合は教えてください)、すべてが機能しているようです。

于 2013-01-09T11:43:53.053 に答える
1

はい、 iterator.closeQuietly() が原因のようですが、コメントアウトの影響により、多くのイテレータが開かれている (実際には閉じられている必要があります) とリークが発生する可能性があります。

代わりに、onQuery() メソッドで、ContentProvider が閉じられると閉じられる Cursor への参照を提供する次のコードを使用してみてください。

Cursor cursor = getHelper().getReadableDatabase().query(tableName, projection, selection, selectionArgs, groupBy, having, sortOrder)
于 2013-06-22T12:36:17.083 に答える