Android HandlerThread 의 사용 및 원리 에 대한 상세 한 설명

5572 단어 AndroidHandlerThread
1.Handler Thread 의 의미
HandlerThread 는 Looper 가 있 는 스 레 드 를 새로 만 들 수 있 습 니 다.이 Looper 는 다른 Handler 를 새로 만 드 는 데 사용 할 수 있 습 니 다.(스 레 드 의 Looper)주의해 야 할 것 은 새로 만 들 때 리 셋 되 어야 한 다 는 것 이다.
2.Handler Thread 의 용법
일반적으로 우 리 는 Handler 를 사용 하여 하위 스 레 드 에서 UI 스 레 드 를 업데이트 합 니 다.그것 은 메 인 스 레 드 에 Looper 순환 이 있 기 때 문 입 니 다.Handler Thread 는 Looper 를 가 진 하위 스 레 드 를 새로 만 들 면 무슨 소 용이 있 습 니까?
시간 소모 작업 을 수행 하 는 것 이 틀림없다.예 를 들 어 데이터 가 실시 간 으로 업 데 이 트 됩 니 다.우 리 는 10 초 마다 표 시 된 데 이 터 를 전환 해 야 합 니 다.만약 에 우리 가 이런 장시간 의 반복 호출 작업 을 UI 스 레 드 에 넣 으 면 실행 할 수 있 지만 이런 조작 이 많 으 면 UI 스 레 드 가 멈 추고 심지어 무 너 지기 쉽 습 니 다.
그래서 하위 스 레 드 에서 이 를 호출 해 야 합 니 다.
HandlerThread 는 Thread 에서 계승 되 었 습 니 다.일반적으로 적응 하 는 장면 은 Thread 와 Handler 의 장점 을 모 아서 장시간 배경 에서 실행 되 고 간격 내(또는 적당 한 상황 에서)호출 되 는 상황 입 니 다.예 를 들 어 위 에서 말 한 실시 간 업데이트 등 입 니 다.
3.2 초 마다 UI 업데이트 실현

public class MainActivity extends AppCompatActivity {
 
  private TextView tvMain;
 
  private HandlerThread mHandlerThread;
  //     handler
  private Handler mThreadHandler;
  //UI    handler
  private Handler mMainHandler = new Handler();
 
  //       Handler    
  private boolean isUpdateInfo;
  //     handler   
  private static final int MSG_UPDATE_INFO = 0x110;
 
  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
 
    tvMain = (TextView) findViewById(R.id.tv_main);
 
    initThread();
  }
 
 
  private void initThread()
  {
    mHandlerThread = new HandlerThread("check-message-coming");
    mHandlerThread.start();
 
    mThreadHandler = new Handler(mHandlerThread.getLooper())
    {
      @Override
      public void handleMessage(Message msg)
      {
        update();//      
 
        if (isUpdateInfo)
          mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
      }
    };
 
  }
 
  private void update()
  {
    try
    {
      //    
      Thread.sleep(2000);
      mMainHandler.post(new Runnable()
      {
        @Override
        public void run()
        {
          String result = "  2       :";
          result += Math.random();
          tvMain.setText(result);
        }
      });
 
    } catch (InterruptedException e)
    {
      e.printStackTrace();
    }
 
  }
 
  @Override
  protected void onResume()
  {
    super.onResume();
    //    
    isUpdateInfo = true;
    mThreadHandler.sendEmptyMessage(MSG_UPDATE_INFO);
  }
 
  @Override
  protected void onPause()
  {
    super.onPause();
    //    
    //       Handler    
    isUpdateInfo = false;
    mThreadHandler.removeMessages(MSG_UPDATE_INFO);
  }
 
  @Override
  protected void onDestroy()
  {
    super.onDestroy();
    //    
    mHandlerThread.quit();
  }
}
4.HandlerThread 원리

public class HandlerThread extends Thread {
  int mPriority;
  int mTid = -1;
  Looper mLooper;
 
  public HandlerThread(String name) {
    super(name);
    mPriority = Process.THREAD_PRIORITY_DEFAULT;
  }
 
 
  public HandlerThread(String name, int priority) {
    super(name);
    mPriority = priority;
  }
 
 
  protected void onLooperPrepared() {
  }
 
  @Override
  public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
      mLooper = Looper.myLooper();
      notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
  }
 
 
  public Looper getLooper() {
    if (!isAlive()) {
      return null;
    }
 
    // If the thread has been started, wait until the looper has been created.
    synchronized (this) {
      while (isAlive() && mLooper == null) {
        try {
          wait();
        } catch (InterruptedException e) {
        }
      }
    }
    return mLooper;
  }
 
 
  public boolean quit() {
    Looper looper = getLooper();
    if (looper != null) {
      looper.quit();
      return true;
    }
    return false;
  }
 
 
  public boolean quitSafely() {
    Looper looper = getLooper();
    if (looper != null) {
      looper.quitSafely();
      return true;
    }
    return false;
  }
 
 
  public int getThreadId() {
    return mTid;
  }
}
우선 HandlerThread 가 Thread 에서 계승 되 는 것 을 볼 수 있 기 때문에 run()에서 의 논 리 는 모두 하위 스 레 드 에서 실 행 됩 니 다.
다음은 두 가지 관건 적 인 방법 입 니 다.run()과 getLooper():
run()에 서 는 Looper 를 간단하게 만 들 고 Looper 를 작 동 시 키 는 논리 임 을 알 수 있 습 니 다.
run()에 mLooper 생 성 이 완료 되면 notify All(),getLooper()에 wait()가 있 는데 무슨 소 용이 있 습 니까?mLooper 가 한 스 레 드 에서 생 성 되 었 기 때문에,우리 handler 는 UI 스 레 드 에서 getLooper()를 호출 하여 초기 화 되 었 습 니 다.
즉,우 리 는 mLooper 가 만들어 질 때 까지 기 다 려 야 정확하게 돌아 갈 수 있다 는 것 이다.getLooper();wait(),notify()는 이 두 스 레 드 의 동기 화 문 제 를 해결 하기 위해 서 입 니 다.

좋은 웹페이지 즐겨찾기