2011-12-16 4 views
0

안드로이드에서 핸들러를 사용하여 별도의 스레드에서 두 개의 메시지를 보내어 UI를 업데이트하는 방법을 궁금합니다. 스레드가 다른 파일에서 선언되었습니다. 자바 스레드를 사용하여 안드로이드에서 바람직하지 않다는 것을 이해하지만 안드로이드 방법을 사용하여 포기, 그들은 끔찍한 있습니다. 핸들러 메시지는 선언 된 스레드에서 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

처리기는 스레드의 루퍼를 바인딩해야합니다. 이 잘못된 것은 안드로이드에서 자바 스레드를 사용하여 없습니다하지만 조금 잔인한 단지 그것을 사용하는 것입니다 당신이 메인 스레드

0

에 메시지를 보낼 수 있습니다 스레드 루퍼에게 지금

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

그리고를 지정하려면이 생성자를 사용하여 주기적으로 메시지를 보내는 것. 권장되는 방법은 Handler.postDelayed입니다. 이 기사에서는 다음과 같은 방법을 제안합니다. 모든 업데이트 코드를 Runnable에 넣고이 Runnable의 run() 끝에 postDelayed 호출을 추가하여 다시 예약합니다. 이 접근법은 백그라운드 스레드가있는 오버 헤드를 제거합니다.

그러나 Handler를 사용하여 다른 스레드에서 메시지를 보내는 것은 쉽습니다. 일부 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*/); 
     // ... 
    } 
} 
같이 구현됩니다

UI를 부분처럼 보인다

관련 문제