2017-02-27 13 views
2

UIスレッドとバックグラウンドスレッド間のスレッド間通信を行う方法はありますか?私はここで共通のハンドラコンセプトを使用してUIを更新します。 私は2つのクラスを使用したいUIスレッドとハンドラを使用する他のスレッドとの通信

new Thread(new Runnable() { 
     public void run() { 
      while (mProgressStatus < 100) { 
       mProgressStatus = doWork(); 

       // Update the progress bar 
       mHandler.post(new Runnable() { 
        public void run() { 
         mProgress.setProgress(mProgressStatus); 
        } 
       }); 
      } 
     } 
    }).start(); 

以下のような概念を持って、一つのクラスは、メインスレッドが含まれ、別のクラスには、バックグラウンドスレッドが含まれていると、彼らは同じハンドラを使用しています。これをどのように実装すればよいですか? 私はそれが非常に一般的だと知っていますが、私はそれを正確に実装することが難しいと思っています。

答えて

1

静的な概念を使用しない場合は、パラメータから何かを渡すことができます。以下のコードでは、私は2つのクラスを実装しています。あなたが尋ねるように、私は両方のスレッドクラスで共通のハンドラを使用しました。私はハンドラh1をRunnableオブジェクトのパラメータとして渡し、別のスレッドクラスのrun()メソッドをトリガするstart()メソッドを渡します。 run()メソッドを含むスレッドはUI(Main)スレッドです。 UIを更新するには、UIスレッドを使用する必要があります。ワーカー(背景)スレッドはUI更新を行うことができません。作業者とUIの間の通信は、ハンドラを介して行われます。そこで、UIスレッドクラスでハンドラh2を定義します。 UIスレッドクラスコンストラクタがバックグラウンドスレッドクラスから呼び出されるとき、コンストラクタから来るh1からh2値を取得します。そして私は私のコミュニケーションにh2を使います。実際、h2とh1はシステム内の同じメモリ空間に属しています。

私は以下の2つのクラスを作成し、参照のためスレッド通信を行いました。

ファーストクラス

public class MainActivity extends AppCompatActivity { 
    Handler h1; 
    Thread t; 
    EditText editText; 
    private Bundle bb = new Bundle(); 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 

     editText = (EditText) findViewById(R.id.editText); 

     h1 = new Handler(Looper.getMainLooper()) { 

      @Override 
      public void handleMessage(Message msg) { 
       bb = msg.getData(); 
       String str = bb.getString("udd"); 
       editText.setText(str); 
       System.out.println(str); 
      } 
     }; 
     t = new Thread(new MyRunnable(h1)); //I pass Runnable object in thread so that the code inside the run() method 
     //of Runnable object gets executed when I start my thread here. But the code executes in new thread 
     t.start(); //thread started 

     try { 
      t.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 


    } 

} 

セカンドクラス

public class MyRunnable implements Runnable { 
    private Handler h2; 
    public MyRunnable(Handler h) { 
     this.h2 = h; 
    } 

    @Override 
    public void run() { 

     //everything inside rum method executes in new thread 
     for(int i=0;i<10;i++) { 
      Message m = Message.obtain(); //get null message 
      Bundle b = new Bundle(); 
      b.putString("udd", "daju"); 
      m.setData(b); 
      //use the handler to send message 
      h2.sendMessage(m); 

     } 
    } 
} 

:thread.start()が発生したとき、それは別のスレッドを作成し、Runnableをクラスの実行をトリガします。したがって、毎回start()を呼び出すと、呼び出し先スレッドと同じ優先度を持つ新しいスレッドがあります。

希望、これはあなたを助けました。

+0

ありがとうございます!それは私のために働いた。 – Gokul

+0

私は嬉しい男@ gd16です –

関連する問題