2011-03-08 2 views
7

처리기를 사용하는 것이 더 좋은 방법입니다. 모든 장점. 필자가 직면 한 모든 예는 인라인 버전을 제공하는 것 같습니다.처리기의 사용 안드로이드

클래스에 구현 된 Handler.Callback을 사용하고 인터페이스 메소드를 구현합니다. 정말 인라인 코드 버전

private Handler mHandler = new Handler(){ ....}; 

답변

5

.

당신은 기본적으로 주요 차이점은 가독성, 코딩 속도, 재사용 및 범위입니다 Java/Android: anonymous local classes vs named classes

이들에 대한 논의에 대한 자세한 내용을보실 수 있습니다.

리소스 관점에서 보면 익명 클래스를 생성하면 Avoid Creating Unnecessary Objects에서 논의 된 것처럼 가비지 수집기에서 오버 헤드가 발생할 수 있습니다. 익명 클래스 작성의 정확한 세부 사항에 대해서는 확신 할 수 없지만 클래스에 인터페이스를 구현하는 것이 더 효율적이라는 것은 논리적입니다.

@WilliamTMallard는 이 아닌의 예를 제공합니다. 그의 예제에서, 길고 구문 론적으로 복잡한 핸들러는 익명 핸들러가 아닌 클래스에 구현되어야합니다. 인라인으로 정의 될 때 읽고 편집하기가 더 어렵 기 때문입니다.

0

이 사용

또는

내가 "가장 좋은 방법은"무엇인지 알 수 없기 때문에 위의 질문에 대한 답변하지 않습니다, 그것은 가능성에 따라 달라집니다 네가하는 일. 그러나 내가하고있는 일과 이유에 대해 설명하겠습니다.

리모컨으로 작동하는 앱을 쓰고 있습니다. 피 제어 장치와 상호 작용할 수있는 여러 가지 활동이 있으며 명령의 결과와 그 활동이 무엇인지에 따라 다른 일이 발생해야합니다. 내가 처리기에 대해 싫어하는 두 가지 사항은 A) "부엌 싱크"구조의 일종이되어 다른 출처의 기능을 구현하고 B) 작업을 분리했다는 것입니다 (제 경우에는 명령 보내기) 그 행동의 결과 처리에서. 그러나 매개 변수로 익명 (올바른 용어? 나는 그런 멍청한.) 처리기를 사용하여 논리를 유지할 수 있습니다. 여기 내 접근 방식에 대한 의사 코드입니다 :

command = "Wake up!"; 

    mDeviceInterface.write(command, new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      switch(msg.what) { 
      case DeviceInterface.MESSAGE_TIMEOUT: // Process the timeout. 
       announce("Device not responding."); 
       break; 
      case DeviceInterface.MESSAGE_READ: // Process the response. 
       byte[] readBuf = (byte[]) msg.obj; 
       if (readBuf[0] == 0x05) { 
        // Success, update device status. 
       } else { 
        announce("Error!"); 
        break; 
       } 
      } 
     } 
    }); 

(. 항상 기억, 이것은 당신이 그것을 위해 지불 한 정확히 아마 가치가있다;)) 일반적인 용어 또는 이러한 인라인 클래스 정의가 익명 클래스입니다

2

http://developer.android.com/reference/android/os/Handler.html

package : android.os 
public class 
Handler 
extends Object 

핸들러는 프로세스 메시지와 스레드의 MessageQueue가와 관련 된 Runnable 객체와를 보낼 수 있습니다. 각 Handler 인스턴스는 단일 스레드 및 해당 스레드의 메시지 큐와 연관됩니다. 새로운 Handler를 만들면, 그 핸들러를 생성하고있는 스레드의 스레드/메시지 큐에 바인딩됩니다. 그 시점부터 메시지와 실행 파일을 해당 메시지 큐에 전달하고 메시지에서 나오는대로 실행합니다 열.

Handler를위한 두 가지 용도가 있습니다

  1. 메시지와보다 Runnable을 예약 할 수있는 미래의 어떤 시점 으로 실행하기는;
  2. 다른 스레드에서 수행 할 작업을 대기열에 넣기 위해 자신의 스레드입니다. 응용 프로그램 시작 페이지

Exmaple 1 개

사용 핸들러. 자식 스레드에서

if (!isFirstIn) { 
    mHandler.sendEmptyMessageDelayed(GO_HOME, SPLASH_DELAY_MILLIS); 
} else { 
    mHandler.sendEmptyMessageDelayed(GO_GUIDE, SPLASH_DELAY_MILLIS); 
} 


/************************************************************************************** 
*1. Handler 
*/ 
private Handler mHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     if(isAuto){ 
      switch (msg.what) { 
      case GO_HOME: 
       goHome(); 
       break; 
      case GO_GUIDE: 
       goGuide(); 
       break; 
      } 
     } 
     super.handleMessage(msg); 
    } 
}; 
private void goHome() { 
    Intent intent = new Intent(SplashActivity.this, MainAct.class); 
    SplashActivity.this.startActivity(intent); 
    SplashActivity.this.finish(); 
} 

private void goGuide() { 
    Intent intent = new Intent(SplashActivity.this, GuideActivity.class); 
    SplashActivity.this.startActivity(intent); 
    SplashActivity.this.finish(); 
} 

예 2

사용 처리기 요청 네트워크는 요청 작업은 시간이 걸리는 경우가 있습니다.

new Thread(new Runnable(){ 
    @Override 
    public void run() { 
     String versionPath = Parameters.getCheckVersionPath(); 
     String result = RequestHelper.doGet(versionPath, null); 
     Message msg = new Message(); 
     Bundle data = new Bundle(); 
     data.putString("result",result); 
     msg.setData(data); 
     handler1.sendMessage(msg); 
    } 
}).start(); 

handler1 = new Handler(){ 
    @Override 
    public void handleMessage(Message msg) { 
     String result = msg.getData().getString("result"); 
     JSONObject obj; 
     try { 
      obj = new JSONObject(result); 
      Map<String, String> versionInfo = Helper.getSoftwareVersion(obj); 
      if (versionInfo != null) { 
       newVersion = versionInfo.get("version"); 
       updateUrl = versionInfo.get("url"); 
      } 
     } catch (JSONException e) { 
      Log.w("net work error!", e); 
     } 
    } 

}; 

예 3

사용 처리기 및 타이머 진행률 표시 줄을 업데이트합니다.

logobar = (ImageView) findViewById(R.id.splash_bar);//progress bar. 
logobarClipe = (ClipDrawable) logobar.getBackground(); 

timer = new Timer(); 
timer.schedule(new TimerTask() { 
    public void run() { 
     updateLogoBarHandler.sendEmptyMessage(0); 
}}, 0, rate); 


/************************************************************************************** 
*2. Handler 
*/ 
//update progress bar. 
private Handler updateLogoBarHandler = new Handler() { 
    public void handleMessage(Message msg) { 
     if(logobarClipe.getLevel() < 10000){ 
      //1.update image. 
      logobarClipe.setLevel(logobarClipe.getLevel() + rate*2); 

      //2.update text. 
      float percent = logobarClipe.getLevel() /100; 
      String percentTxtVerbose = String.valueOf(percent); 
      String percentTxt = percentTxtVerbose.substring(0, percentTxtVerbose.indexOf('.')) + "%"; 
      bartxt.setText(percentTxt); 

     }else{ 
      timer.cancel(); 
     } 
     super.handleMessage(msg); 
    } 
}; 
0

Android에서 익명의 클래스를 사용하는 것은 위험합니다. this blog post 한 바와 같이 -

자바에서 비 정적 내부 익명 클래스는 외부 클래스 암시 기준을 잡아.

여기에 누수가 발생할 수 있습니다.

따라서 짧은 대답은 인터페이스 메서드를 구현하거나 정적 클래스 (외부 클래스 참조를 보유하지 않음)를 사용하는 것입니다.

private static class ChangeTextHandler extends Handler { 
    private final WeakReference activity; 

    public ChangeTextHandler(MainActivity activity) { 
     this.activity = new WeakReference<>(activity); 
    } 

    @Override 
    public void handleMessage(Message msg) { 
     MainActivity activity = this.activity.get(); 
     if (activity == null) { 
      Log.e(TAG, "Activity is null ChangeTextHandler.handleMessage()!"); 
      return; 
     } 

     final String text = (String) msg.getData().get(BUNDLE_KEY); 
     if (!TextUtils.isEmpty(text)) { 
      switch (msg.what) { 
       // do something 
      } 
     } 
    } 
} 

가 나는 blog post around usage of Handlers을했다, 그래서뿐만 아니라 확인 :

가치가있을 수도 있습니다 :

예를 들어, 누출 안전 핸들러는 다음과 같이 수

관련 문제