2011-01-28 8 views
3

私のAndroid NDKアプリケーションでは、C++ライブラリはUIスレッドとは異なるスレッドで実行されます。 C++からのJNI呼び出しは、JavaクラスFooのインスタンスを作成します。私はUIスレッドで作成された別のJavaオブジェクトBarをFoo上のメソッドを呼び出すようにしたいと思います。それ、どうやったら出来るの?Android/Java:別のスレッドで作成されたオブジェクトのメソッドを呼び出す方法は?

難易度:Fooには、対応するJNI関数をC++ライブラリから呼び出すいくつかのネイティブメソッドがあります。これらの呼び出しがスレッドセーフであることを保証するにはどうすればよいですか?

難易度2:Barのメソッドの中には、実際にはWebViewClientのコールバックメソッドをオーバーライドするものがあります。いくつかのメソッドのリターンコードは、Fooのメソッド呼び出しの結果に依存します。 Fooへの呼び出しは直ちに実行する必要があります。

+0

実際、スレッドから同期結果が必要なデザイン全体は、おそらく悪臭を放ちます。 JNIライブラリがレガシーまたは第三者でない限り、FooをUIスレッドに移行することを検討してください。 –

+0

まず、メソッドがJNIを通じて呼び出されているという事実を無視して始めてください。スレッドの安全性の問題は、使用しているプログラミング言語に大きく依存しません。 – fadden

+0

難易度ボーナス3!これはすべて、開発中のクロスプラットフォームライブラリの一部です。クライアントは主にC++インタフェースを使用します.C++インタフェースはUIとは別のスレッド上でAndroid上で動作します。デザインのこの部分は不変で、私にはアクセスできません。したがって、これを実装することの難しさ。 – djcouchycouch

答えて

0

ハンドラクラスを試してください。 Fooコンストラクタでハンドラを構築します。何らかの方法でBarクラスへの参照を渡します。バーにHandler.post()を呼び出します。

これが機能するには、スレッドにメッセージキューが必要です。純粋にワーカースレッドの場合、メソッドを直接呼び出すことは答えではありません。スレッド中断メカニズムAFAIRはありません。 stuffをワーカースレッドに渡すためには、メッセージキューをいくらかシミュレートする必要があります(Barが追加するRunnnableオブジェクトのキューがあり、それを時々検査する必要があります)。

スレッドの安全を確保することは別の大きな質問です。 SOは、この話題について言及され実行されたすべてのために十分ではありません。だから、

+0

私は何らかのメッセージキューを使用することを考えていましたが、私は陳列棚に乗ってきました。バーのメソッドの中には、実際にはWebViewClientのコールバックメソッドをオーバーライドするものがあります。いくつかのメソッドのリターンコードは、Fooのメソッド呼び出しの結果に依存します。 Fooへの呼び出しは直ちに実行する必要があります。私はメインのポストにこの詳細を追加します。 – djcouchycouch

+0

スレッドがブロックされています。これはかなり吸う。 UIスレッドがワーカースレッドが応答するのを待つようにすることは、スレッド化の目的を全滅させることになります。言い表せないことは非常に壊れやすいことです(もし労働者が反応しなければどうでしょうか?)。つまり、Object.wait()メソッドとnotify()メソッドはあなたの友人(時には敵)です。 –

0

あなたは、スレッド1と2を持っているが、スレッド2は、オブジェクトを作成し、スレッド1が2

は、あなたが書かれたスレッド2に基本的にオブジェクトを持っていませんでしたスレッドでメソッドをオブジェクトを呼び出すしたいオブジェクトを持っています同期されたキーワードを使用するような標準的なJavaスレッドの同期技術を持つjava?スレッド上

例えばJavaコード:メッセージの中に埋め込まれた通知のコールバック・ルーチンと

// object of this type instantiated on thread 2 and called from thread 1 
public class thread2Class { 
    public void doSomething(...) { 
     synchronized (this) { 
      // call java or jni mthod 
     } 
    } 
} 
0

ダブルメッセージキュー。 スレッド1はスレッド2キューにコールバックアドレスのメッセージを送信します。 スレッド2はメッセージを処理し、スレッド1のキューに結果通知を送信します。 スレッド1は、送信した元のメッセージに関連付けられたコールバックルーチンを呼び出します。 スレッド1キューはUIメッセージキューであり、スレッド2は独自のキュー実装です。 スレッド2は、ライブラリ呼び出しのマネージャ/ラッパーです。 ブロッキングなし、待機なし。 スレッド1が状態を管理しなければならない場合、応答が到着したときにどのメッセージがポストされるかを制御する状態モデルを更新します。

0

おそらくbeginInvoke()のようなものを利用して、メッセージを適切な方法でスレッドにキューイングしようとします。 hereは、beginInvoke()Activity.runOnUiThread()、または適切に利用されているAsyncTask()のいずれかで嘲笑されることが認められている。

関連する問題