2011-12-16 4 views
0

アンドロイドでハンドラーを使用して別のスレッドから2つのメッセージを送信してUIを更新する方法が不思議でした。スレッドは別のファイルで宣言されています。私は、Javaスレッドを使用してAndroidで望ましくないことを理解するが、私はアンドロイドメソッドを使用してあきらめて、彼らはひどいです。ハンドラメッセージは、宣言されたスレッドから200ミリ秒ごとに送信されます。私はそれを実装する方法のまともな例を見つけることができません。別ファイルのスレッドからAndroidでハンドラーを実装する方法

ここは私の拡張スレッドです。これはアクティビティから呼び出されます。

import java.io.IOException; 

import android.media.MediaPlayer; 
import android.os.Bundle; 
import android.os.Message; 

public class MPlayer extends Thread { 
    private volatile boolean playing = false; 
    private volatile boolean finished = false; 
    MediaPlayer player; 
    Message msg; 
    Bundle bundle; 
    String filepath; 

    /* other fields, constructor etc. */ 
    public MPlayer(String path) { 
     filepath = path; 
     player = new MediaPlayer(); 
     bundle = new Bundle(); 
     msg = new Message(); 
     start(); 
    } 

    public void seekMPlayer(int i) { 
     // TODO Auto-generated method stub 
     player.seekTo(i); 
    } 

    public boolean getPlaying() { 
     // TODO Auto-generated method stub 
     return playing; 
    } 

    @Override 
    public void run() { 
     try { 
      player.setDataSource(filepath); 
      player.prepare(); 
     } catch (IllegalArgumentException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IllegalStateException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 

     while (!finished) { 
      while (playing && !finished) { 
       try { 
        Thread.sleep(200); 
        if (playing && !finished) { 
         bundle.putString("progval", songTime()); 
         // msg.setData(bundle); 
         // threadHandler.sendMessage(msg); 
        } else 
         break; 
       } catch (InterruptedException e) { 

       } 
      } 
     } 

    } 

    public synchronized void pauseMPlayer() { 
     playing = false; 
     player.pause(); 

    } 

    public synchronized void PlayMPlayer() { 
     playing = true; 
     player.start(); 
     // call notify() here when you switch to wait/notify. 
    } 

    public void stopMPlayer() { 
     playing = false; 
     finished = true; 
     player.release(); 
     // call notify() here too. 
    } 

    private String songTime() { 
     // TODO Auto-generated method stub 
     if (filepath != null) { 
      int progressseconds = (int) ((player.getCurrentPosition()/1000) % 60); 
      int progressminutes = (int) ((player.getCurrentPosition()/1000)/60); 
      int durationseconds = (int) ((player.getDuration()/1000) % 60); 
      int durationminutes = (int) ((player.getDuration()/1000)/60); 
      String progmin, progsec, durmin, dursec; 
      if (progressminutes >= 10) 
       progmin = Integer.toString(progressminutes); 
      else 
       progmin = "0" + Integer.toString(progressminutes); 
      if (progressseconds >= 10) 
       progsec = Integer.toString(progressseconds); 
      else 
       progsec = "0" + Integer.toString(progressseconds); 
      if (durationminutes >= 10) 
       durmin = Integer.toString(durationminutes); 
      else 
       durmin = "0" + Integer.toString(durationminutes); 
      if (durationseconds >= 10) 
       dursec = Integer.toString(durationseconds); 
      else 
       dursec = "0" + Integer.toString(durationseconds); 
      return (progmin + ":" + progsec + "/" + durmin + ":" + dursec); 
     } else { 
      return ("No File!"); 
     } 
    } 
} 

答えて

1

ハンドラは、スレッドのルーパーをバインドする必要があります。スレッドルーパー

Handler handler = new Handler(Looper.getMainLooper()); 

を指定するには、このコンストラクタを使用して、今、あなたは、メインスレッドに

0

をメッセージを送ることができますがあり、Javaスレッドを使用することには何の問題もアンドロイドではありませんが、ちょうどそれを使用するためにビット過剰です定期的なメッセージを送信する。これを行うには、Handler.postDelayedを使用することをお勧めします。この記事では、以下の方法を提案しています:すべての更新コードをRunnableに入れて、このRunnableのrun()の最後にpostDelayedコールを追加して、もう一度スケジュールしてください。このアプローチは、バックグラウンドスレッドを持つオーバーヘッドを排除します。

しかし、ハンドラを使用して他のスレッドからメッセージを送信するのは簡単です。私が理解しているように、あなた自身が更新できるように、いくつかのUIコンポーネントにメッセージを送信しようとしています。 私のアプリケーションでは、同様の問題に直面しました。 UIコンポーネント内でハンドラを宣言し、このハンドラをコンストラクタパラメータのバックグラウンドスレッドに渡しました。

UI部分は次のようになります。

class MyActivity extends Activity { 
    Handler mHandler = new Handler() { 
     public void handleMessage(Message msg) { 
      // update UI according to a content of msg from background thread 
      // ... 
     } 
    }; 

    private Thread mBackgroundWorker = new BackgroundThread(mHandler); 

    protected void onCreate(Bundle savedInstanceState) { 
     // ... 
     mBackgroundWorker.start(); 
     // ... 
    } 

    protected void onDestroy() { 
     // we created the thread in this activity 
     // so we should manage its lifecycle here 
     mBackgroundWorker.interrupt(); 
    } 
} 

とバックグラウンドスレッドが

class BackgroundThread extends Thread { 

    private final mHandler; 

    public BackgroundThread(Handler h) { 
     mHandler = h; 
    } 


    public void run() { 
     // do some processing... 
     mHandler.sendMessage(/*some message to update an UI*/); 
     // ... 
    } 
} 
のように実装されています
関連する問題