コードを見ないと、何が起こっているのかわかりません。しかし、最初に思いつくのは、ネットワーク リクエストが別のスレッドで発生しているためperformFiltering()
、空の結果セットが早まって返されている可能性があるということです。その時点でpublishResults()
、空の結果が返され、ドロップダウンは空です。後で AsyncTask が結果を取得し、その結果をアダプターのリストに追加しますが、何らかの理由でまだ表示されません。
ただし、AsyncTask の必要性について誤解している可能性があると思います。Filter オブジェクトはすでに AsyncTask と同様の処理を行っています。これ performFiltering()
はバックグラウンド スレッドで行われ、publishResults()
performFiltering() の終了後に UI スレッドから呼び出されます。したがって、ネットワーク リクエストを performFiltering() で直接実行し、結果を FilterResults オブジェクトに設定できます。ネットワーク リクエストが遅すぎて UI に問題が発生することを心配する必要はありません。
もう少し複雑な代替ソリューションですが、それは私が Filter オブジェクトで行っていることです (バックグラウンドで API 呼び出しを行う既存のアーキテクチャのため、 performFiltering( ))、クロススレッド監視を行うために wait()/notify() で同期オブジェクトを使用することです。そのため、結果は performFiltering() でネットワーク要求を直接行うのと同じですが、実際には複数のスレッドで発生しています。
// in Filter class..
protected FilterResults performFiltering(CharSequence constraint) {
APIResult response = synchronizer.waitForAPI(constraint);
// ...
}
// callback invoked after the API call finishes:
public void onAPIComplete(APIResult results) {
synchronizer.notifyAPIDone(results);
}
private class Synchronizer {
APIResult result;
synchronized APIResult waitForAPI(CharSequence constraint) {
someAPIObject.startAsyncNetworkRequest(constraint);
// At this point, control returns here, and the network request is in-progress in a different thread.
try {
// wait() is a Java IPC technique that will block execution until another
// thread calls the same object's notify() method.
wait();
// When we get here, we know that someone else has just called notify()
// on this object, and therefore this.result should be set.
} catch(InterruptedException e) { }
return this.result;
}
synchronized void notifyAPIDone(APIResult result) {
this.result = result;
// API result is received on a different thread, via the API callback.
// notify() will wake up the other calling thread, allowing it to continue
// execution in the performFiltering() method, as usual.
notify();
}
}
ただし、最も簡単な解決策は、ネットワーク リクエストを performFiltering() メソッドで直接同期的に実行することであることがわかると思います。上記のコード例は、非同期/コールバック駆動型 API 呼び出し用のアーキテクチャが既にあり、その動作を変更して performFiltering() で同期結果を取得したくない場合の 1 つの可能性にすぎません。