2017-06-25 13 views
1

私はcountdowntimerを別のスレッドに入れ、各ティックでUIを更新します。私がスタートをクリックするたびに、アプリはただ閉じて、私は 'app has stopped'というエラーメッセージを表示します。CountdownTimerアプリがクラッシュするティックでUIスレッドを更新しようとしています

public class Activity_MultiplayerGame extends AppCompatActivity { 

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

public void btnStart_onClick(View view){ 
    CountDownTimer timer = new CountDownTimer(15000, 1000){ 

     @Override 
     public void onTick(final long millisUntilFinished) { 
      runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        TextView countdownText = (TextView) findViewById(R.id.countdown); 
        Integer timeUntilFinished = (int) millisUntilFinished/1000; 
        countdownText.setText(timeUntilFinished); 
       } 
      }); 
     } 

     @Override 
     public void onFinish() { 
      TextView countdownText = (TextView) findViewById(R.id.countdown); 
      countdownText.setText("Finished"); 
     } 
    }; 

    timer.start(); 
} 
} 

CountDownTimerを作成すると、独自のスレッドが生成されるという前提がありますか?

+0

スタックトレースを提供します。 –

+0

エラーは何ですか? –

答えて

0

アンドロイドのメイン(UI)スレッド以外のスレッドからUIを更新することはできません。問題にアプローチする方法はたくさんありますが、本当に別のスレッドが必要な場合は、AsyncTaskから開始する必要があります。 doInBackroundメソッドとonProgressUpdateメソッドを確認してください。

HandlerクラスとpostAtTime(Runnable、long)、postDelayed(Runnable、long)メソッドをチェックすることができます。他のスレッドは必要ありません。または、Handlerクラスのサブクラスを作成し、sendMessageDelayed(android.os.Message、long)とhandleMessage()をオーバーライドした組み合わせを使用できます。あなたが実際に表示される文字列リソースのIDではなく整数を受け取りsetText(int)方法に整数を渡した

countdownText.setText(timeUntilFinished); 

0

はここにあなたの問題です。メソッドsetText(String)を使用する必要があります。

これを試してみてください:

countdownText.setText(String.valueOf(timeUntilFinished)); 
1

あなたはHandler使用することができます。私はこのコードは1秒ごとショーカウンタを増やし、のTextViewカウンタ値を更新します

のためのサンプルを書きました。

public class MainActivity extends Activity { 


    private Handler handler = new Handler(); 
    private TextView textView; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     textView = (TextView) findViewById(R.id.text); 
     startTimer(); 
    } 


    int i = 0; 
    Runnable runnable = new Runnable() { 
     @Override 
     public void run() { 
      i++; 
      textView.setText("counter:" + i); 
      startTimer(); 
     } 
    }; 

    public void startTimer() { 
     handler.postDelayed(runnable, 1000); 
    } 

    public void cancelTimer() { 
     handler.removeCallbacks(runnable); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     cancelTimer(); 
    } 
} 
+0

しかし、UIスレッドにバインドされたハンドラはありませんか? setTextを呼び出すとUIのラグやフリーズが発生しませんか? カウントダウンが有効なときに、ユーザーがテキストボックスに入力してボタンとやりとりできるようにしたい。 – Jamanfi

+0

それは仕事です!私は私の電話でそれをテストしました。また、ExoPlayerがこのコードを使用してビデオプレーヤーのプログレスバーを更新しています –

+0

コードをテストして何が起こるかを確認してください –

0

このコードも、それは(あなたが好きまたは増加)カウンタを減らす働き、同じボタンをテキストビューであなたも停止することができますかクリックを経由してカウンタリセットを示しています。

public class MainActivity extends AppCompatActivity { 


TextView textView; 
Button count; 

boolean timelapseRunning = true; 
int NUM_OF_COUNT=15; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    textView=(TextView)findViewById(R.id.textview); 
    count=(Button)findViewById(R.id.count); 
    runTimer(); 

} 
public void onclick(View view){ 
    if (!timelapseRunning) { 
     timelapseRunning=true; 
    } else { 
     timelapseRunning = false; 

    } 
    if(NUM_OF_COUNT==0){ 
     NUM_OF_COUNT=15; 
    } 
} 
private void runTimer() { 
      final Handler handler = new Handler(); 
    handler.post(new Runnable() { 
     @Override 
     public void run() { 
      textView.setText(""+NUM_OF_COUNT); 
      if (!timelapseRunning && NUM_OF_COUNT>0) { 
       NUM_OF_COUNT--; 
      } 
      handler.postDelayed(this, 1000); 
     } 
    }); 
} 
} 
0

CountDownTimerは、作成された同じスレッドでコールバックを行います。したがって、CountDownTimerコンストラクタがUIスレッドで呼び出された場合、onTickrunOnUiThreadは絶対に必要ありません。 onTick方法で呼び出される

また、

TextView countdownText = (TextView) findViewById(R.id.countdown); 

findViewById方法は、かなりの処理能力を消費するように、貧弱な設計です。

最後Nabinバンダリとして実際の問題が指摘setTextメソッドに渡された整数値です。それを文字列にラップする必要があります。 このコードは十分です

final TextView countdownText = (TextView) findViewById(R.id.countdown); 
    CountDownTimer timer = new CountDownTimer(15000, 1000) { 
     @Override 
     public void onTick(long millisUntilFinished) { 
      countdownText.setText(String.valueOf(millisUntilFinished/1000)); 
     } 

     @Override 
     public void onFinish() { 
      countdownText.setText("Finished"); 
     } 
    }; 
    timer.start(); 
関連する問題