-2

カウントダウンタイマーを表示するために使用できるテキストビューが1つあります。Runnable インターフェースを取る Thread クラスを使いたかったのです。

同じために次のコードを書きましたが、残念ながら実行時エラーが発生します ThreadApp has Stopped

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.TextView;

public class MainActivity extends Activity implements Runnable
{

TextView tvTimer;
Thread timerThread;
int time=30;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    tvTimer =(TextView)findViewById(R.id.textView1);
    timerThread= new Thread(this);
    timerThread.start();
}

@Override
public boolean onCreateOptionsMenu(Menu menu)
{
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void run()
{
    try
    {
        Thread.sleep(1000);
        tvTimer.setText((String.valueOf(time)).toString());
        time--;
    }
    catch (InterruptedException e)
    {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

tvTimer.setText((String.valueOf(time)).toString());を削除したと同時に それは正常に動作します。誰でも私に解決策を提供できますか?私はアンドロイドが初めてです。

4

5 に答える 5

5

このようにRunOnUiThreadを使用してUIの更新を使用できます

 @Override
    public void run()
    {
    try
    {
        Thread.sleep(1000);
       runOnUiThread(new Runnable() {
      public void run() {
              tvTimer.setText((String.valueOf(time)).toString());                       
        }
        });
        time--;
      }
      catch (InterruptedException e)
      {
        // TODO Auto-generated catch block
        e.printStackTrace();
       }

     }
于 2013-05-30T06:35:58.663 に答える
2

tvTimer.setText((String.valueOf(time)).toString()); を削除したとき それは正常に動作します

非UIスレッドからTextViewテキストを変更しようとしているため、runOnUiThreadまたはHandlerを使用してTextViewを他のスレッドから更新します

于 2013-05-30T06:31:24.313 に答える
1

タイマー タスクで UI を更新しようとしています。タイマー タスクは別のスレッドで実行されます。ui スレッドで ui を更新します。ハンドラーまたは runonuithread を使用する

       Handler m_handler;
       Runnable m_handlerTask ;  
       m_handler = new Handler();
       m_handlerTask = new Runnable()
       {
         @Override 
         public void run() {
            tvTimer.setText((String.valueOf(time)).toString()); 
            timer--;
                   // do something 
              m_handler.postDelayed(m_handlerTask, 1000); // instad of 1000 mention the delay in milliseconds
         }
       };
       m_handlerTask.run(); 

または使用

@Override
public void run()
{
try
{
    Thread.sleep(1000); 
    // should not call thread.sleep() bad design
    // check the edit below
     runOnUiThread(new Runnable(){

              @Override
              public void run(){
                //update ui here
                 tvTimer.setText((String.valueOf(time)).toString()); 
              }
           });

    time--;
}
catch (InterruptedException e)
{
    // TODO Auto-generated catch block
    e.printStackTrace();
}
}

編集:スレッド内で Thread.sleep() を使用するのは悪い設計です。

http://developer.android.com/training/articles/perf-anr.html

ドキュメントからの引用。

Thread または HandlerThread を実装する場合は、ワーカー スレッドが完了するのを待っている間に UI スレッドがブロックされないように注意してください。 Thread.wait() または Thread.sleep() を呼び出さないでください。ワーカー スレッドが完了するのを待っている間にブロックする代わりに、メイン スレッドは完了時に他のスレッドがポストバックするための Handler を提供する必要があります。このようにアプリケーションを設計すると、アプリの UI スレッドが入力に応答し続けることができるため、5 秒の入力イベント タイムアウトによって発生する ANR ダイアログを回避できます。

停止するには、この m_handler.removeCallbacks(m_handlerTask); を使用します。

于 2013-05-30T06:31:33.417 に答える
0

UI 要素、つまりスレッド内の TextView を更新しようとしています。スレッドでこれを行うことはできません。代わりに、ハンドラーを使用して、次のように UI 要素に変更を投稿します。

   Handler handler = new Handler();

    @Override
    public void run()
    {
        try
        { 
            Thread.sleep(1000);
            handler.post(new Runnable()
            {
                public void run() 
                {
                    tvTimer.setText((String.valueOf(time)).toString());
                }
            time--;
            });
        }
        catch (InterruptedException e)
        {
             // TODO Auto-generated catch block
             e.printStackTrace();
        }

     }
于 2013-05-30T06:31:46.570 に答える