2016-03-23 9 views
1

私はServiceを持っています。これは私のアプリが起動するとバックグラウンドで実行され、アプリが終了した後も引き続き実行されます。それは登録UriLoader.OnLoadCompleteListener<Cursor>Content Providerからのimplementsです。新しいCursorオブジェクトは、コールバックメソッドonLoadComplete(Loader<Cursor> loader, Cursor data)に配信されると私はその後Parcelableinterfaceを実装するカスタムObjectsArrayListを作成するためにCursorを使用してAsyncTaskを実行します。一度処理されると、アプリケーションが開かれていれば、HandlerMessenger,MessagesBundle)を使用してIPCフレームワークを使用してマーシャリング/デマーシャルされたアプリケーションに返信されます。アプリケーションが開いていない場合、ArrayListは開かれたときにServiceに呼び出されたアプリケーションを一度開いた状態に戻す準備ができています。Androidの例外:FAILED BINDER TRANSACTION

問題:

ArrayListが比較的大きく得ることができます(それが唯一のPrimitivesと、いくつかの短いStringオブジェクトBitmapsを含まない)と膨大な量がArrayListは約700になったとき、それはFAILED BINDER TRANSACTIONを打つ意味オブジェクト。

現在のソリューション

私はチャンクにArrayListを分割し、それがその後のAppで1 ArrayListに再構成して使用されるHandlerに戻っていくつかのMessagesを送信しています(更新(つまり、ハックビットを感じています) RecyclerViewsなど)。

パフォーマンスが大幅に改善されたため、このアプローチを使用します。アプリケーションが開かれるたびに常にContent Providerを照会するのではなく、最初にApp/Serviceが開始されたときに初めてクエリを実行するだけです。

私は 'ハッキー'と言う理由は、解決策ではなくBinder Frameworkという制限の回避策のように感じるからです。

これに違う方法でアドバイスすることは歓迎されます。

答えて

1

私の心に来る2つの選択肢がある:

  1. は、サービス内の静的ArrayListのを持って、カーソルが内部にある静的ArrayListの内容をコピーするために活動を受け取ったときにブロードキャストを送信します活動の中で地元のarraylistのサービス。このようにして、アクティビティは、コンテンツをコピーするときにのみ静的なアラレイリストの参照を持ちます。

    私は非同期にsqlデータベースの内容を保存し、その後、データベースからカーソルを非同期的に取得するためにブロードキャストをアクティビティに送信します。 UIスレッドでは、アダプターのnotifydatasetChangedを呼び出します。

+0

お返事いただきありがとうございます。両方のアイデアは非常に妥当です。私は静的なArrayListを使うことを考えましたが、スコープの理由から静的変数を避けようとしました。この場合、他のスレッドがアクセスして同時に変更しようとするグローバル変数にアクセスします。私はおそらく、SQLデータベースに行くか、まったく別のアプローチを使用して再起動します。 –

+0

私は第2のアプローチにも行くと思いますが、私はあなたの観察に同意します。私も興味がある別の答えを得ることができれば興味深いでしょう。 – z3n105

+0

私は別のアプローチをとることに決めました - 私はカスタムAsyncTaskLoaderを使用します - これは、正しく実装されていれば、私は後の安定性を提供する必要があります。このインスタンスのデータベースを使用すると、プロセスを倍増させるように感じます。つまり、コンテンツプロバイダにクエリを行い、自分のデータベースにデータを挿入すると、プロセスを倍増させるように感じます。データベースを再度クエリし、カスタムPOJOオブジェクトはとにかくそれを形成する。 –