2012-04-19 9 views
0

にアクセスすると、スレッドで作成されたハンドラにアクセス中にnullポインタ例外が発生することがあります。ハンドラの作成を同期させて、

私は2つのアプローチを使用しています。

私はハンドラを作成し、サービスメソッドでアクセスするスレッドを持つサービスです。 2番目のスレッドはアクティビティで作成されています。スレッドでは、スレッドを作成し、起動し、ハンドラを作成します。

問題は非常に簡単で、ハンドラはメインスレッドとは非同期で作成されます。そして私はメイン(GUIスレッド)でアクセスしているので、時にはそれが作成され、時には取得時にnullになることがあります。

(ハンドラ== null){ } 私はguiスレッドで作成できましたが、それは本当に悪い解決策です。私はこれを行うためのエレガントな方法を探しています。

すべてがメインスレッドにあります。

Thread t = new Thread(new Runnable { 
Looper.prepare(); 
handler = new Handler(); 
Looper.Loop(); 
} 
handler.post(new Runnable{}) //at this point sometimes handler is still null. 
and it is created like few ms later. But still at this point i need valid handler 
to background thread 
+2

はあなたのコードをしてください追加することができますが、私はよく非常によくあなたの問題 – FUBUs

答えて

0
  1. 「投手」属性は、whileループや睡眠を使用してunelegantでなく、間違っていないだけで、揮発性でない限り - あなたはハンドラがnullでないことが判明した場合でも、あなたはそれを使用することはできません。ハンドラへの書き込みとハンドラインスタンスの作成との間には、先験的な関係は存在しないので、主スレッドは、そのコンストラクタが実行前にハンドラへの参照を参照することがあります。

  2. 単純な参照を渡す安全な選択は、SynchronousQueue(実際にはキューではなく、内部の容量はなく、スレッド間でオブジェクトを移動するためだけです)です。


    final SynchronousQueue<Handler> giveMeHandler = new SynchronousQueue(); 
    new Thread(new Runnable(){ 
     public void run(){ 
      Handler handler; 
      // create a Handler; 
      giveMeHandler.put(handler); // blocks until handler taken; 
     } 

    }).start(); 

    Handler handler = giveMeHandler.take(); // blocks until handler given 
+0

btw:何をしたいのですか?GUIスレッドを停止しています(新しいハンドラを取得するのに必要な非常に短い時間)。まったく停止しないことに真剣なら、コールバックを作成して新しいスレッドにハンドラを渡さなければなりません。 – fdreger

+0

なので、基本的にはレイアウトなどを作っていますが、ハンドラが作成された後に実行したいアクションはすべてコールバックに入れられますか?右? – Drake29a

+0

私は本当にその質問に従っていないのですか?私は、あなたがハンドラが利用可能になるのを待つことを望むので、それは本質的に「ブロッキング」だと言っただけです。何らかの理由でブロックする必要がない場合は、ハンドラが必要なコードを "onHandlerCreated(Handler)"のようなメソッドに移動する必要があります。あなたはそのメソッドへの呼び出しをrunOnUiThreadします。物事は常にそのように働きます:あなたは非同期呼び出しをブロックするか、それに切り替えるかのどちらかです。率直に言えば、私はあなたがルーパーを虐待していると思わせ、エグゼクティブサービスを代わりに使うべきです(実際には上流に行くことを意味しません)。 – fdreger

0

Javaソースの並行パッケージを使用することができます。 考えられる解決策:

彼らはあなたのための同期ロジックをカプセル化します。

CyclicBarrier cb = new CyclicBarrier(2); 
... 
T1: 
cb.await(); 
T2: 
cb.await(); 

CyclicBarrierを(またはたCountDownLatch)が障壁を待っている(この場合は2)のスレッドの一定量刚性待機します:

あなたのコードは次のようになります。

+0

を理解しないが、私は、GUIのスレッドを停止することはできません:あなたは(私の頭のオフ、いくつかのタイプミス可能性が高い)のようにそれを使用しますJava/Androidで、言い換えれば私はできるが、それは解決策ではなく、少なくともエレガントではない。 Guiスレッドの外にあるすべてのロジックを動かすことは痛いでしょう。 – Drake29a

+0

申し訳ありませんが、私たちがアップデートスレッドについて話していたことに気付きませんでした。さて私は[AsyncTask](http://developer.android.com/reference/android/os/AsyncTask.html)の使用をお勧めしたいと思います。 – Sambuca

+0

さて、AsyncTaskは一般的でシンプルなものに最適です。私はスレッドとその可能性を使用する必要があります。 – Drake29a

関連する問題