2014-09-25 2 views
0

내 목록보기에 chronometer이 있습니다. 문제는 때로는 다른 탭으로 이동했거나 목록보기 항목을 스크롤하여 볼 수 없거나 심지어 Home 버튼을 누른 후에도 누수가 발생하여 매초마다 OnChronometerTickListener이 실행되는 것을 볼 수 있다는 것입니다. 실제로 볼 때만 실행해야하므로 리소스 낭비 인 것 같습니다.목록보기의 크로노 미터가 누출되는 경우가 있음

이 동작을 피하는 방법이 있습니까? 가끔씩 만 발생한다는 점에 유의하십시오.

public class TimerLayout extends LinearLayout { 

    private static final String LOG_TAG = "TimerLayout"; 
    Button btn_endTimer; 
    Button btn_cancelTimer; 
    Chronometer cmt_timer; 
    Runnable updateTimerThread; 
    Handler handler; 

    public TimerLayout(Context context, AttributeSet attrs) { 
     super(context,attrs); 

     setOrientation(LinearLayout.VERTICAL); 

     LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     inflater.inflate(R.layout.timer, this, true); 
     cmt_timer = (Chronometer) getChildAt(0); 
     btn_endTimer = (Button) ((ViewGroup) getChildAt(1)).getChildAt(0); 
     btn_cancelTimer = (Button) ((ViewGroup) getChildAt(1)).getChildAt(1); 

     btn_endTimer.setOnClickListener(new OnClickListener(){ 
      @Override 
      public void onClick(View view){ 
       cmt_timer.stop(); 
      } 
     }); 

     btn_cancelTimer.setOnClickListener(new OnClickListener(){ 

      @Override 
      public void onClick(View view){ 
       cmt_timer.stop(); 
      } 
     }); 

     cmt_timer.setOnChronometerTickListener(new OnChronometerTickListener() { 

      @Override 
      public void onChronometerTick(Chronometer arg0) { 
       if(BuildConfig.DEBUG){Log.d(LOG_TAG,"onChronometerTick.objectid=" + System.identityHashCode(TimerLayout.this));} 

      } 
     }); 

    } 

    public void init(Date startTime){ 
     cmt_timer.stop(); 
     if(startTime!=null){ 
      Date now = new Date(); 
      long elapsedTime = now.getTime() - startTime.getTime(); 
      cmt_timer.setBase(SystemClock.elapsedRealtime() - elapsedTime); 
      cmt_timer.start(); 
     } 

    } 

} 

나는 그것을 시작하는 내 cursorAdaptorbindView() 방법이 클래스의 init 메서드를 호출합니다.

답변

1

트릭은 onPause() 조각/활동의 크로노 미터를 중지하는 것입니다.

  1. 반환 init()에서 크로노 개체 :

    public class ChronometerHolder { 
        private WeakHashMap<Date, Chronometer> chronometerMap; 
        private static final String LOG_TAG = "ChronometerHolder"; 
    
        public ChronometerHolder() { 
         chronometerMap = new WeakHashMap<Date, Chronometer>(); 
        } 
    
        public void add(Date dt_startTime, Chronometer chronometer){ 
         chronometerMap.put(dt_startTime, chronometer); 
        } 
    
        public void remove(Date dt_startTime){ 
         chronometerMap.remove(dt_startTime); 
        } 
    
        public int getCount(){ 
         return chronometerMap.size(); 
        } 
    
        public void startAll() { 
         // start any chronometers that were paused 
         if (chronometerMap.size() > 0) { 
          Set<Entry<Date, Chronometer>> set = chronometerMap.entrySet(); 
          Iterator<Entry<Date, Chronometer>> iterator = set.iterator(); 
          Entry<Date, Chronometer> entry; 
          while (iterator.hasNext()) { 
           entry = (Entry<Date, Chronometer>) iterator.next(); 
           entry.getValue().start(); 
           } 
          } 
         } 
        } 
    
        public void stopAll() { 
         // stop any chronometers that might be running 
         if (chronometerMap.size() > 0) { 
          Set<Entry<Date, Chronometer>> set = chronometerMap.entrySet(); 
          Iterator<Entry<Date, Chronometer>> iterator = set.iterator(); 
          Entry<Date, Chronometer> entry; 
          while (iterator.hasNext()) { 
           entry = (Entry<Date, Chronometer>) iterator.next(); 
           entry.getValue().stop(); 
           } 
          } 
         } 
        } 
    

    그런 다음 내가 아래에 변경 :

    은 그래서 크로노 미터를 개최 클래스를 생성

    public Chronometer init(Date startTime){ 
        Chronometer obj = null; 
        cmt_timer.stop(); 
        if(startTime!=null){ 
         Date now = new Date(); 
         long elapsedTime = now.getTime() - startTime.getTime(); 
         cmt_timer.setBase(SystemClock.elapsedRealtime() - elapsedTime); 
         cmt_timer.start(); 
         obj = cmt_timer; 
        } 
    
        return obj; 
    
    } 
    
  2. 조각에서 홀더 클래스를 인스턴스화하십시오 :

    ChronometerHolder chronometerHolder = new ChronometerHolder(); 
    
  3. 당신이합니다 (CursorAdapterbindView() 단위) chrononmeter를 초기화 할 때마다, 홀더에 추가 : onPause()에서

    Chronometer tmpChronometer = viewHolder.myTimer.init(dt_hitSessionStartTime); 
    if(tmpChronometer != null){ 
        chronometerHolder.add(dt_hitSessionStartTime, tmpChronometer); 
    } 
    
  4. , 모든 크로노 미터를 중지

    chronometerHolder.stopAll(); 
    
  5. onResume()에서 모든 크로노 미터를 시작하십시오.

    chronometerHolder.startAll(); 
    

는 당신이 응용 프로그램을 종료하지 않고 홈 버튼을 누른 다음 bindView() 호출이 실행되지 않습니다, 다시 응용 프로그램을 열 때. 즉, 크로노 미터가 멈춘 상태에 있음을 의미합니다. 따라서 # 5에서와 같이 onResume()으로 시작해야합니다.

관련 문제