2017-02-07 1 views
1

나는 안드로이드 CountDownTimer에 문제가있다.안드로이드에서 .cancel() 문제 Countdown Timer

나는 JAVA/Android를 배우려고 노력 중이며 커피를 양조 할 때 내 자신을위한 간단한 응용 프로그램을 시작했습니다. 카운트 다운 타이머가 작동하려면 .cancel() 함수를 가져올 수 없습니다. 이 포럼 및 다른 포럼에서 여러 스레드를 읽었습니다.

내 자바 코드 :

package jandidrik.kaffe; 

import android.content.Context; 
import android.os.CountDownTimer; 
import android.os.Vibrator; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.widget.Button; 
import android.widget.SeekBar; 
import android.widget.SeekBar.OnSeekBarChangeListener; 
import android.widget.TextView; 
import android.view.View; 
import android.widget.Toast; 

import java.util.concurrent.TimeUnit; 


public class MainActivity extends AppCompatActivity implements OnSeekBarChangeListener { 

private SeekBar WaterSeekBar, CoffeeSeekBar, BloomingSeekBar, BrewingSeekBar; 
private TextView WaterText, CoffeeText, BloomingText, BrewingText, TimerText; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    WaterSeekBar = (SeekBar) findViewById(R.id.WaterSeekBar); 
    CoffeeSeekBar = (SeekBar) findViewById(R.id.CoffeeSeekBar); 
    BloomingSeekBar = (SeekBar) findViewById(R.id.BloomingSeekBar); 
    BrewingSeekBar = (SeekBar) findViewById(R.id.BrewingSeekBar); 

    WaterText = (TextView) findViewById(R.id.WaterText); 
    CoffeeText = (TextView) findViewById(R.id.CoffeeText); 
    BloomingText = (TextView) findViewById(R.id.BloomingText); 
    BrewingText = (TextView) findViewById(R.id.BrewingText); 
    TimerText = (TextView) findViewById(R.id.Timer); 

    WaterSeekBar.setOnSeekBarChangeListener(this); 
    CoffeeSeekBar.setOnSeekBarChangeListener(this); 
    BloomingSeekBar.setOnSeekBarChangeListener(this); 
    BrewingSeekBar.setOnSeekBarChangeListener(this); 

    WaterSeekBar.setProgress(1000); 
    WaterText.setText(Integer.toString(WaterSeekBar.getProgress())); 
    CoffeeSeekBar.setProgress(63); 
    CoffeeText.setText(Integer.toString(CoffeeSeekBar.getProgress())); 

    Long Minutes = TimeUnit.SECONDS.toMinutes(BrewingSeekBar.getProgress()); 
    Long Seconds = BrewingSeekBar.getProgress() - TimeUnit.MINUTES.toSeconds(Minutes); 
    BrewingText.setText("" + String.format("%01d:%02d", Minutes, Seconds)); 
} 

@Override 
public void onProgressChanged(SeekBar Bar, int progress, boolean fromUser) { 
    switch (Bar.getId()) { 
     case R.id.WaterSeekBar: 
      WaterText.setText(Integer.toString(progress)); 
      break; 
     case R.id.CoffeeSeekBar: 
      CoffeeText.setText(Integer.toString(progress)); 
      break; 
     case R.id.BloomingSeekBar: 
      BloomingText.setText(Integer.toString(progress)); 
      break; 
     case R.id.BrewingSeekBar: 
      Long Minutes = TimeUnit.SECONDS.toMinutes(BrewingSeekBar.getProgress()); 
      Long Seconds = BrewingSeekBar.getProgress() - TimeUnit.MINUTES.toSeconds(Minutes); 
      BrewingText.setText("" + String.format("%01d:%02d", Minutes, Seconds)); 
      break; 
    } 
} 

@Override 
public void onStartTrackingTouch(SeekBar Bar) { 
} 

@Override 
public void onStopTrackingTouch(SeekBar Bar) { 
} 

public void Brew(View V) { 

    final Button BrewButton = (Button) V; 
    final String ButtonText = BrewButton.getText().toString(); 

    CountDownTimer Count = new CountDownTimer(BrewingSeekBar.getProgress() * 1000, 1000) { 

     @Override 
     public void onTick(long millisUntilFinished) { 
      Long Minutes = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished); 
      Long Seconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(Minutes); 

      TimerText.setText("" + String.format("%01d:%02d", Minutes, Seconds)); 

      int VibrateTime = BrewingSeekBar.getProgress() - BloomingSeekBar.getProgress(); 

      if ((TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished)) == VibrateTime) { 
       Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
       // Vibrate 500ms 
       v.vibrate(500); 

       Toast.makeText(MainActivity.this, "Blooming is finnished!", Toast.LENGTH_LONG).show(); 
      } 
     } 

     @Override 
     public void onFinish() { 
      TimerText.setText("Finished!"); 
     } 
    }; 

    if (ButtonText.equals("Start Brewing!")) { 
     Count.start(); 
     BrewButton.setText("Stop Timer!"); 
    } else { 
     Count.cancel(); 
     BrewButton.setText("Start Brewing!"); 
    } 
} 
} 

내 XML 코드 : 당신은 CountDownTimer의 잘못된 인스턴스를 중지하려고

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/activity_main" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
android:keepScreenOn="true"> 
tools:context="jandidrik.kaffe.MainActivity"> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Adjust Amount of water (ml)" 
    android:layout_marginBottom="8dp" 
    android:layout_marginTop="16dp" 
    /> 

<LinearLayout 
android:layout_width="match_parent" 
android:layout_height="wrap_content"> 

<SeekBar 
    android:id="@+id/WaterSeekBar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:max="1200" 
    android:progress="1000" 
    android:layout_weight="2" 
    /> 

<TextView 
    android:id="@+id/WaterText" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_weight="14" 
    android:text="1000" 
    android:layout_marginLeft="8dp" 
    /> 

</LinearLayout> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Adjust Amount of coffee (g)" 
    android:layout_marginBottom="8dp" 
    android:layout_marginTop="8dp" 
    /> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

<SeekBar 
    android:id="@+id/CoffeeSeekBar" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:max="100" 
    android:progress="63" 
    android:layout_weight="2" 
    /> 

    <TextView 
     android:id="@+id/CoffeeText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="63" 
     android:layout_weight="14" 
     android:layout_marginLeft="8dp" 
     /> 

</LinearLayout> 

<TextView 
    android:layout_width="match_parent" 
    android:layout_height="1dp" 
    android:background="@android:color/darker_gray" 
    android:layout_marginTop="52dp" 
    android:layout_marginBottom="52dp" 
    /> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Set the blooming time (s)" 
    android:layout_marginBottom="8dp" 
    /> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <SeekBar 
     android:id="@+id/BloomingSeekBar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:max="60" 
     android:progress="30" 
     android:layout_weight="2" 
     /> 

    <TextView 
     android:id="@+id/BloomingText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="30" 
     android:layout_weight="14" 
     android:layout_marginLeft="8dp" 
     /> 

</LinearLayout> 

<TextView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Set the total brewing time (m:ss(" 
    android:layout_marginBottom="8dp" 
    android:layout_marginTop="8dp" 
    /> 

<LinearLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:orientation="horizontal"> 

    <SeekBar 
     android:id="@+id/BrewingSeekBar" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:max="480" 
     android:progress="240" 
     android:layout_weight="2" 
     /> 

    <TextView 
     android:id="@+id/BrewingText" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:text="4 min 0 s" 
     android:layout_weight="14" 
     android:layout_marginLeft="8dp" 
     /> 

</LinearLayout> 

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

<Button 
    android:id="@+id/BrewButton" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Start Brewing!" 
    android:layout_centerInParent="true" 
    android:layout_marginTop="16dp" 
    android:layout_marginBottom="16dp" 
    android:onClick="Brew" 

    /> 

</RelativeLayout> 

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content"> 

<Chronometer 
    android:id="@+id/Timer" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:textSize="30sp" 
    android:format="%s:%s" 
    android:layout_centerInParent="true" 
    /> 
</RelativeLayout> 

</LinearLayout> 
+0

"작동하지 않을 수 있습니다."... 어떻게됩니까? 타이머가 멈추지 않는거야? 기대 한 것과 기대 한 것에 대해 매우 구체적이어야합니다. – nhouser9

답변

0

. 코드를 수정하는 가장 간단한 방법은 Count을 메소드 밖으로 이동하는 것입니다.

private CountDownTimer currentCount; 
public void Brew(View v) { 
    final Button BrewButton = (Button) V; 
    final String ButtonText = BrewButton.getText().toString(); 

    if (ButtonText.equals("Stop Timer!") && currentCount != null) { 
     currentCount.cancel(); 
     currentCount = null; 
     BrewButton.setText("Start Brewing!"); 
     return; 
    } 

    currentCount = new CountDownTimer(BrewingSeekBar.getProgress() * 1000, 1000) { 

     @Override 
     public void onTick(long millisUntilFinished) { 
      Long Minutes = TimeUnit.MILLISECONDS.toMinutes(millisUntilFinished); 
      Long Seconds = TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished) - TimeUnit.MINUTES.toSeconds(Minutes); 

      TimerText.setText("" + String.format("%01d:%02d", Minutes, Seconds)); 

      int VibrateTime = BrewingSeekBar.getProgress() - BloomingSeekBar.getProgress(); 

      if ((TimeUnit.MILLISECONDS.toSeconds(millisUntilFinished)) == VibrateTime) { 
       Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
       // Vibrate 500ms 
       v.vibrate(500); 

       Toast.makeText(MainActivity.this, "Blooming is finnished!", Toast.LENGTH_LONG).show(); 
      } 
     } 

     @Override 
     public void onFinish() { 
      TimerText.setText("Finished!"); 
     } 
    }; 

    currentCount.start(); 
    BrewButton.setText("Stop Timer!"); 
} 
0

BrewButton 클릭 할 때마다 호출은 또 다른 '새로운'CountDownTimer 할당하고 Count 변수에 할당 될 브루() 메소드로 이루어집니다. 이 변수 선언을 Brew 메소드의 범위 밖으로 이동할지 여부는이 변수를 변경하지 않습니다. 결과적으로 .cancel()에 대한 호출은 잘못된 CountDownTimer 개체에서 수행 될 수 있습니다.

원래 CountDownTimer 개체에 대한 프로그램 참조가 손실되었지만 가비지 수집 될 때까지 계속 실행 중이며 여전히 .onTick() 및 .inFinish() 메서드라고합니다.

해결 방법은 하나의 CountDownTimer 객체에만 매달리고, 사용자가 두 번째로 BrewButton을 눌러 타이밍을 멈추었을 때 해당 객체를 참조하고 새 객체를 할당하지 않도록하는 것입니다.

아마도 Count을 클래스 범위에 넣고 NULL로 초기화 한 다음 Count이 NULL 일 때만 Brew() 메서드에서 새 인스턴스를 인스턴스화 할 수 있습니다. 그런 다음 if (StartBrewing) 성명에서, 당신은 내가 독자들에게 연습으로이 작업을 수행 할 정확한 코드를 떠날거야 Count.cancel()

에 전화 후 NULL에 Count 다시 재설정하고 있는지 확인합니다.