2012-02-13 12 views
3

私はLinkedBlockingQueueを "プロデューサ - メディエータ - コンシューマ"モデルのメディエータに持っています。 Producerはまず、メディエータをactivityQueueに追加して更新します。次に、コンシューマ/アクティビティは待ち行列で待ち受けて待機し、次の項目を取得します。キューからアクティビティを更新する最良の方法

キューのサイズが変更されたことを確認し、次のアイテムを取得するアクティビティが必要です。 メディエータはアクティビティの可視性がありませんアクティビティのみがメディエータを見ることができます。では、私が望むこのリスナーメカニズムをどうやって作りますか?

ここでは、キューを保持するメディエータクラスがあり、アクティビティによって何らかの形でキューが参照され、更新が必要かどうかの情報が得られます。キューに入ってくるデータは、時には不安定で無作為になる可能性があるため、ポーリングメカニズムは機能しません。

public class MediatorData { 

    /** Queue for the Activity */ 
    LinkedBlockingQueue <byte[]> queueConsumer = new LinkedBlockingQueue <byte[]>(); 

    /** 
    * Add data to a queue(s) for consumption 
    */ 
    public void put(byte[] data) throws InterruptedException { 
     queueConsumer.add(data); 
    } 

    /** 
    * Return data from the queue for the Feature calculations 
    */ 
    public byte[] getFeatureData() throws InterruptedException { 
     return queueConsumer.poll(100, TimeUnit.MILLISECONDS); 
    } 

} 

私のアクティビティクラスのグラフクラスで、キューリスナは効率的で高速でなければなりません。 ObserverObservableの使用に関する

public class DisplayGraph extends Activity { 

    // populated from Application Class where its created 
    pirvate MediatorData md; 

    public void onCreate(Bundle savedInstanceState) { 
     md = getMediator(); // This comes from the custom Application class 

     ... some type of listener to queue 
    } 

    private void getQueueData() { 
     byte[] tv = md.queueConsumer.poll(); 
     // can't update textview get exception CalledFromWrongThreadException 
     ((TextView) DisplayGraph.this.findViewById(R.id.tv)).setText("TV " + tv[0]); 
    } 
} 

答えて

1

最良の方法はこれを行うことです:前の答えはそれでエラーが

は次のようなものだろう。

public class MediatorData extends Observable { 

    /** Queue for the Activity */ 
    LinkedBlockingQueue <byte[]> queueConsumer = new LinkedBlockingQueue <byte[]>(); 

    /** 
    * Add data to a queue(s) for consumption 
    */ 
    public void put(byte[] data) throws InterruptedException { 
     queueConsumer.add(data); 
     notifyObservers(); 
    } 

    /** 
    * Return data from the queue for the Feature calculations 
    */ 
    public byte[] getFeatureData() throws InterruptedException { 
     return queueConsumer.poll(100, TimeUnit.MILLISECONDS); 
    } 
} 

表示アクティビティではUIスレッドで更新を実行する必要があるため、runOnUiThreadメソッドを使用してください。

public class DisplayGraph extends Activity implements Observer { 

    // populated from Application Class where its created 
    private MediatorData md; 

    byte[] tv; 

    public void onCreate(Bundle savedInstanceState) { 
     md = getMediator(); // This comes from the custom Application class 
     md.addObserver(this); 
    } 

    private void getQueueData() { 
     tv = md.queueConsumer.poll(); 
     runOnUiThread(setRunnable); 
    } 

    public void update(Observable arg0, Object arg1) { 
     getQueueData(); 
    } 

    // Need to do this to update the data to the UI. 
    final Runnable setImageRunnable = new Runnable() { 
     public void run() { 
      ((TextView) DisplayGraph.this.findViewById(R.id.tv)).setText("TV " + tv[0]); 
     } 
    }; 
} 
1

どのように?

public class MediatorData extends Observable { 

    /** Queue for the Activity */ 
    LinkedBlockingQueue <byte[]> queueConsumer = new LinkedBlockingQueue <byte[]>(); 

    /** 
    * Add data to a queue(s) for consumption 
    */ 
    public void put(byte[] data) throws InterruptedException { 
     queueConsumer.add(data); 
     setChanged(); 
     notifyObservers(); 
    } 

    /** 
    * Return data from the queue for the Feature calculations 
    */ 
    public byte[] getFeatureData() throws InterruptedException { 
     return queueConsumer.poll(100, TimeUnit.MILLISECONDS); 
    } 
} 

そして、この:このような状況に対処するために

public class DisplayGraph extends Activity implements Observer { 

    // populated from Application Class where its created 
    private MediatorData md; 

    public void onCreate(Bundle savedInstanceState) { 
     md = getMediator(); // This comes from the custom Application class 
     md.addObserver(this); 
    } 

    private void getQueueData() { 
     byte[] tv = md.queueConsumer.poll(); 
     // can't update textview get exception CalledFromWrongThreadException 
     ((TextView) DisplayGraph.this.findViewById(R.id.tv)).setText("TV " + tv[0]); 
    } 

    public void update(Observable arg0, Object arg1) { 
     getQueueData(); 
    } 
} 
+0

私はいくつかのコードを掲載しましたが、このコードで観察可能なパターンがどのように使用されるかを教えてください。 – JPM

+0

Observersについてもこれを見てきましたが、スレッドセーフではない方法がいくつかありましたか? http://stackoverflow.com/q/5123121/346309 – JPM

+0

私は例を追加しました。スレッドの問題を認識していませんでしたが、この方法を使用する場合は、提供したリンクで解決策を試すことができます。 – gelupa

関連する問題