2017-06-16 1 views
1

特定のView(プロデューサと呼ぶ)に発生するMotionEventsと、そのデータを表示目的で読み取る別のスレッドの別のコード(消費者と呼ぶ)を格納するコードがあります。私は本質的に、標準的なAndroidボタンを使用することが実現不可能なダウンカラーのワンカラーアップの異なるカラーボタン機能を再作成しています。 MotionEventは単一のArrayListに格納されます。これへのアクセスは、プロバイダとコンシューマがArrayListへのI/O処理と一時データの読み取りを行わないように、単一の許可セマフォにラップされます。すべての井戸と良い。共有リソース上のセマフォの衝突を処理するためのベストプラクティスは何ですか?

このビューを高速でタップしているときに問題が発生します。プロデューサ側では、MotionEvent.ACTION_DOWNに応答してArrayListに項目を追加し、MotionEvent.ACTION_UP(ACTION_MOVEs無視)に対応してリストから削除します。私の消費者がArrayListを読んでいるために、または以前のタップを処理していないために、電話をタップでフラッディングすると、追加/削除するときにセマフォが利用できなくなります。

この問題のベストプラクティスは何ですか?私がMOTION_DOWNを逃した場合、私はそれを無視することができるようですが、私はMOTION_UPを逃しても、私の消費者は指を押したままのようにボタンを表示し続けることはありませんか? MOTION_UPが見つからないことが原因で発生する可能性のある表示バグ(高速タップとは関係ありません)が表示されます。

+0

「セマフォが閉じられる」とはどういう意味ですか? – EJP

+0

ダムタイプミス、申し訳ありません。私はセマフォが利用できないことを意味します。 – user1733212

+0

私はあなたの問題を完全に理解していませんが、いくつかのコードは助けがはるかに良いでしょうが、試してみましょう。 Androidは完全にJava 7をサポートしていますか?ですから、これを制御するためにJavaの高水準並行オブジェクトに依存しないでください。https://docs.oracle.com/javase/tutorial/essential/concurrency/highlevel.html、より信頼性の高いものになるでしょう。配列リストをスレッドセーフにする別のオプション:Collections.synchronizedList(new ArrayList <>()) ' –

答えて

0

あなたのスキームが現在間違っているとは分かりませんが、おそらく同期の問題があります。

生産者消費者向けのパターンの場合は、BlockingQueueが最適です。あなたの場合、単純な無制限の実装を使用してください。

ボタンのクリックに応じてmBlockingQueue.add(MotionEvent)を実行し、バックグラウンドスレッドで無限ループでイベントを消費する:サイドノートとして

while(true) { 
    processEvent(mBlockingQueue.take()); 
} 

:私はあなたが本当にために、バックグラウンドスレッドを必要とすることはないと思いますクリックするとボタンの色が変わります。 other simpler waysがあります。

+0

@Vasilly私はあなたの提案の後にBlockingQueueに関するいくつかの調査を行いました。私はCopyOnWriteArrayListを使って巻いたので、その一般的な方向で私を指摘してくれてありがとう。 – user1733212

関連する問題