web-dev-qa-db-ja.com

Androidプログラムを「待機」させる方法

プログラムを特定のミリ秒数だけ一時停止させたいのですが、これをどのように正確に行うのですか?

Thread.sleep( time )などのさまざまな方法を見つけましたが、それが必要だとは思いません。コードを特定の行でxミリ秒間停止させたいだけです。任意のアイデアをいただければ幸いです。

これはCの元のコードです...

extern void delay(UInt32 wait){
    UInt32 ticks;
    UInt32  pause;

    ticks = TimGetTicks();
    //use = ticks + (wait/4);
    pause = ticks + (wait);
    while(ticks < pause)
        ticks = TimGetTicks();
}

待機時間はミリ秒です

10
JuiCe

まず最初に、ビジーループで遅延を実装しないでください。私はそれがどこから来ているのかを見ることができます-Palmパイロットは組み込みのsleep()関数のないシングルプロセスデバイスだったと思いますが、マルチプロセスデバイスでは、そのようなビジーループは全体をもたらしますその膝にプロセッサ。それはあなたのバッテリーを殺し、通常のシステムタスクが適切に実行されるのを防ぎ、他のプログラムを遅くするか、それらを完全に停止し、デバイスを応答不能にし、あなたの手でそれを熱くさせることさえあります。

探している呼び出しはThread.sleep()です。睡眠中に発生する割り込み例外をキャッチするように設定する必要があります。

2番目に、Android(またはほとんどすべての最新のGUIシステム))などのイベントベースのユーザーインターフェイスを使用すると、UIスレッドでスリープする必要がなくなります。これにより、デバイス全体がフリーズし、結果が他のポスターが述べたように、ANR(Activity Not Responding)クラッシュの場合、最も重要なのは、これらの小さなフリーズがユーザーエクスペリエンスを完全に台無しにすることです。

(例外:ユーザーが気付かないほど短い間隔でスリープしている場合は、それでうまくいくでしょう。1/ 4秒はおそらく問題ありませんが、状況によってはアプリケーションが不安定になる可能性があります。)

残念ながら、ループベースのアプリケーションをイベントベースのシステムに移植している場合、目的の操作を実行するための簡潔で洗練された方法はありません。

つまり、適切な手順は、UIスレッドでハンドラーを作成し、それに遅延メッセージを送信することです。遅延されたメッセージはアプリケーションを「起動」し、それをトリガーして、遅延後に何をするかを実行します。

このようなもの:

View gameBoard;     // the view containing the main part of the game
int gameState = 0;  // starting
Handler myHandler;

public void onCreate(Bundle oldState) {
  super.onCreate(oldState);
  ...
  gameBoard = findViewById(R.layout.gameboard);
  myHandler = new Handler();
  ...
}

public void onResume() {
  super.onResume();
  displayStartingScreen();
  myHandler.postDelayed(new Runnable() { 
    gotoState1(); 
  }, 250);
}

private void gotoState1() {
  // It's now 1/4 second since onResume() was called
  displayNextScreen();
  myHandler.postDelayed(new Runnable() { 
    gotoState2();
  }, 250);
}
...
9
Edward Falk

このようにUIスレッドをスリープさせるべきではありません。これを行うと、ActivityNotResponding例外でアプリケーションを強制終了する可能性があります。

一部のコードの実行を一定時間遅らせたい場合は、次のようなRunnableとHandlerを使用します。

Runnable r = new Runnable() {
    @Override
    public void run(){
        doSomething(); //<-- put your code in here.
    }
};

Handler h = new Handler();
h.postDelayed(r, 1000); // <-- the "1000" is the delay time in miliseconds. 

このようにしてもコードは遅延しますが、UIスレッドを「フリーズ」させることはできません。その結果、せいぜいパフォーマンスが低下し、ANRは最悪の場合強制的に終了します。

17
FoamyGuy

次のようなことをしてください。 参照 へのリンクは次のとおりです。これは役立つ場合があります。

final MyActivity myActivity = this;   

    thread=  new Thread(){
        @Override
        public void run(){
            try {
                synchronized(this){
                    wait(3000);
                }
            }
            catch(InterruptedException ex){                    
            }

            // TODO              
        }
    };

    thread.start();   
3
prolink007

これを行うには、HandlerクラスとpostDelayed()メソッドを使用できます。

Handler h =new Handler() ;
h.postDelayed(new Runnable() {
    public void run() {
                 //put your code here
              }

            }, 2000);
}

2000 msは、関数内のコードを実行する前の遅延時間です

2

プログラムを一時停止する理由がわかりません。バックグラウンドでいくつかのタスクを実行して結果を使用する場合は、 AsyncTask を確認してください。しばらく前に 同様の質問 がありました。

1

SystemClock.sleep(millis)は、Thread.sleep(millis)とよく似たユーティリティ関数ですが、InterruptedExceptionを無視します。

1
Ken

私はThread.sleep(....)がおそらくあなたが望んでいることだと思うのですが、正しく実行していない可能性があります。いったい何を止めようとしているのですか?うまくいけば、UIスレッドはありませんか?何らかの間隔でいくつかのタスクを実行しているバックグラウンドスレッドがあると思いますか?その場合、Thread.sleepは特定のスレッドを一定時間スリープ状態にしますが、すべてのスレッドを一時停止するわけではありません。

0
Jon Taylor
try {
    Thread.sleep(2000); //1000 milliseconds is one second.
}
catch (InterruptedException e) 
{
    e.printStackTrace();
}
0
rmoore