2011-08-22 12 views
6

AsyncTaskLoaderにいくつかの問題があります。ローダーを再起動しようとしたときに、それらが関連しているかどうかは不明です。私のアプリケーションでは、1つのシングルトンのLoaderManagerによって管理されるカスタムAsyncTaskLoaderの3つのインスタンスによってバックアップされたカスタムCursorAdapterのインスタンスが3つあります。問題は、二つのdifferenctアダプタ/ローダ対に関連するが、使用されるコードは、いずれの場合にも同様である。カスタムAsyncTaskLoaderコールバックの問題

getLoaderManager().restartLoader(loaderId, bundle, loaderManager); 

問題1:私はrestartLoader(呼び出し)とLoaderManagerが1つonCreateLoaderへの呼び出しを登録しなくonLoaderReset()。 LoaderはdeliverResult()に到達しますが、onLoadFinished()は呼び出されません。 Loaderには、 'reset'フラグも 'started'フラグもありません(下記のコードを参照)。

問題2:私はrestartLoader()を呼び出し、LoaderManagerはonLoaderReset()の呼び出しを登録します。 LoaderはonReset()に到達しますが、それ以上は取得されません。 Cursorはnullに設定されていますが、新しいCursorはロードされません。

どのような問題が発生する可能性がありますか?カーソルを作成し、データベースでそれをポイントすると、あなたは、

@Override 
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) { 
    return new CustomCursorLoader(); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    cursorAdapter.changeCursor(cursor); 
} 

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

答えて

1

「LoaderManager」とは、実際にはLoaderManager.LoaderCallbacks<D>インターフェイスの実装です。あなたは別の名前を使用したいかもしれませんが、これは混乱します。なぜそれはシングルトンですか?これは、通常、アクティビティーまたはフラグメント、場合によってはインターフェースを実装するアクティビティー/フラグメントに結び付けられます。ローダー(アクティビティ/フラグメント)はどこで作成していますか?またLoaderManager.initLoader()onCreate()/onActivityCreated()から呼び出してください。そうしないと、ローダーが正しく起動しないことがあります。

+0

1.ええ、私はその名前が明らかではないことを知っています、ごめんなさい。 2.もうシングルトンではありません。その部分で作業していました。 3.主な問題は、同じローダーで同じカーソルを別のアクティビティに結びつけることです。 – Pikaling

+0

なぜあなたはカーソルを共有したいですか?ローダーはアクティビティー/フラグメントによって管理されるため、別のアクティビティーが終了するとローダーがクローズする可能性があります。同じLoader _class_を使用し、異なるアクティビティ/フラグメントでインスタンス化することができます。 –

+0

ご協力ありがとうございます。私はすべてのコードを書き直して、すべて作業しています。時には私はOOPが嫌い... – Pikaling

0

CustomCursorLoader.java

@Override 
protected void onStartLoading() { 
    Log.v(TAG, "Starting Loader"); 
    if (lastCursor != null) { 
     deliverResult(lastCursor); 
    } 
    if (takeContentChanged() || lastCursor == null) { 
     forceLoad(); 
    } 
} 

@Override 
public void deliverResult(Cursor cursor) { 
    Log.v(TAG, "Delivering result"); 
    if (isReset()) { 
     Log.v(TAG, "reset"); 
     if (cursor != null) { 
      cursor.close(); 
     } 
     return; 
    } 
    Cursor oldCursor = lastCursor; 
    lastCursor = cursor; 
    if (isStarted()) { 
     Log.v(TAG, "started"); 
     super.deliverResult(cursor); 
    } 
    if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { 
     oldCursor.close(); 
    } 
} 

@Override 
protected void onReset() { 
    Log.v(TAG, "Reset"); 
    super.onReset(); 
    onStopLoading(); 
    if (lastCursor != null && !lastCursor.isClosed()) { 
     lastCursor.close(); 
    } 
    lastCursor = null; 
} 

CustomCursorLoaderManager.java:ここでローダおよびLoader Manager用のコードの一部ですnullに設定することはできません。明示的にカーソルを閉じるか、タイムアウトするまでデータベースをロックします。

この修正を実装するには、Androidのライフサイクルと既存のコールバックを活用することをおすすめします。

希望すると便利です。

+0

良いキャッチ - それはchangeCursor()でなくてはならないswapCursor() - 今変更しました – Pikaling

+0

あなたはまだ同じ問題を抱えていますか? – Codeman

+0

いいえ私はそれを修正しようとし、それを悪化させた!いつも通り... – Pikaling

関連する問題