web-dev-qa-db-ja.com

ハンドラーで一時停止し、postDelayed in android

私はAndroidプログラミングに慣れていないので、初心者のことはご容赦ください。レイアウトの中央に1つのTextViewがあり、それをそのまま使用する非常に単純なアクティビティを作成しようとしています。数秒ごとに別のテキストに切り替えます。たとえば、TextViewは「text1」と言い、数秒間一時停止してから「text2」と言って、もう一度一時停止します。最終的に、テキストを追加してすべて循環させたいと思います。これは非常に単純なことのように思えますが、現時点では主にスレッドとハンドラーについて学習しようとしています。とにかく、UIスレッドから長いものを遠ざけて防止する方法について読みました。エラーが発生したため、ハンドラーを使用して画面上の2つのテキストを切り替えるだけだと思いました。残念ながら、これを機能させることはできません。コードを次に示します。

public class MainActivity extends Activity {

String[] myarray = {"text1" , "text2"};
int arraylength = myarray.length;
int count;
Handler handler = new Handler();

TextView mytexts;

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

    mytexts = (TextView)findViewById(R.id.my_texts);
    mytexts.setText(myarray[0]);

    Thread t = new Thread( new Runnable(){
        public void run() {
            for (int count = 0; count < arraylength; count++){
                handler.postDelayed(new Runnable(){
                    public void run() {
                        mytexts.setText(myarray[1]);
                    }                   
                }, 7000);
            }
        }
    });
    t.start();
    }
}

Logcatで確認できることから、ハンドラーはpostDelayedを次々に実行しているようです(私のコードの場合、postDelayで別のpostDelayedを実行するのに7秒待機しません)。また、「mytexts.setText(myarray [1]);」を1にしたいと思います。 forループの「count」と同じであるため、配列内の文字列の1つと同じにすることができますが、エラーが発生します。私はこれに何時間も立ち往生しており、オンラインで見つけた他の例は、他のことに取り組む前に主に基本を理解したい私のような人には複雑すぎるようです。これのいずれかで少しでも助けていただければ幸いです。ありがとうございました。

10
John Octavious

postDelayedは非ブロッキングです。つまり、後でこれを行うキューに追加します。したがって、おそらく表示されているのは、すべてのテキスト更新が7秒目に一緒に行われていることです。これは、実際にはpostDelayまたはonCreateから実行したいのに、onResumeメソッドからonPostResumeを実行しているためです。

また、実行可能ファイルをポストキューに追加するスレッドを作成する理由はありません。コードは次のようになります:(乗数を遅らせる時間に注意してください)

@Override
protected void onResume() {
    super.onResume();
    for (int count = 0; count < arraylength; count++){
        handler.postDelayed(new Runnable(){
            @Override
            public void run() {
                mytexts.setText(myarray[count]);
            }
        }, 7000 * (count + 1));
    }
}
19
JRomero

これは、ループがすべてのハンドラーを7秒後に実行するように設定しているためです。7秒後ではなく、7秒後に実行されます。 postDelayedメソッドを追加するか、ハンドラーでpostAtTimeメソッドを使用できます。

また、スレッドでこれを行う必要はありません。これを完全に取り除くことができます。

2
Ali