私はAndroidエミュレータの画面に一定の間隔でテキストを表示するアプリケーションを開発しました。私はHandler
クラスを使っています。これが私のコードの抜粋です。
handler = new Handler();
Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
}
};
handler.postDelayed(r, 1000);
このアプリケーションを実行すると、テキストは一度だけ表示されます。どうして?
あなたの例への簡単な修正は:
handler = new Handler();
final Runnable r = new Runnable() {
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(r, 1000);
あるいは、通常のスレッドを使用することもできます(オリジナルのRunnerを使用)。
Thread thread = new Thread() {
@Override
public void run() {
try {
while(true) {
sleep(1000);
handler.post(this);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
実行可能なオブジェクトをメッセージキューに送信して実行できるコマンドと見なし、handlerをそのコマンドを送信するためのヘルパーオブジェクトと見なすことができます。
詳細はこちら http://developer.Android.com/reference/Android/os/Handler.html
私は毎秒正しい更新のためのAlex2k8の最初の解決策を向上させることができると思います
1.オリジナルコード:
public void run() {
tv.append("Hello World");
handler.postDelayed(this, 1000);
}
2.分析
tv.append("Hello Word")
cost Tミリ秒と仮定します。3.解決策
それを回避するにはpostDelayed()の順序を変更するだけで、遅延を回避できます。
public void run() {
handler.postDelayed(this, 1000);
tv.append("Hello World");
}
new Handler().postDelayed(new Runnable() {
public void run() {
// do something...
}
}, 100);
繰り返し作業に使用できます
new Timer().scheduleAtFixedRate(task, runAfterADelayForFirstTime, repeaingTimeInterval);
いいね
new Timer().scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
}
},500,1000);
上記のコードは、最初にhalf second(500)の後に実行され、各second(1000)の後に繰り返されます
どこで
taskは実行されるメソッドです
after最初の実行までの時間
(間隔繰り返し実行時間)
二番目に
また、タスクを何度も実行したい場合は、CountDownTimerを使用することもできます。
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}.start();
//Above codes run 40 times after each second
そして、あなたはまたrunnableでそれをすることができます。のような実行可能なメソッドを作成する
Runnable runnable = new Runnable()
{
@Override
public void run()
{
}
};
そして両方の方法でそれを呼びなさい
new Handler().postDelayed(runnable, 500 );//where 500 is delayMillis // to work on mainThread
OR
new Thread(runnable).start();//to work in Background
私はこの典型的なケース、すなわち一定の間隔で何かを走らせるためには、Timer
がより適切であると思います。これは簡単な例です:
myTimer = new Timer();
myTimer.schedule(new TimerTask() {
@Override
public void run() {
// If you want to modify a view in your Activity
MyActivity.this.runOnUiThread(new Runnable()
public void run(){
tv.append("Hello World");
});
}
}, 1000, 1000); // initial delay 1 second, interval 1 second
Timer
を使用することにはいくつかの利点があります。
schedule
関数の引数で簡単に指定できますmyTimer.cancel()
を呼び出すだけでタイマーを止めることができます。myTimer.cancel()
before を新しいスレッドのスケジューリングの前に呼び出してください(myTimerがnullでない場合)。Handler handler=new Handler();
Runnable r = new Runnable(){
public void run() {
tv.append("Hello World");
handler.postDelayed(r, 1000);
}
};
handler.post(r);
Handler.post()メソッドの説明を正しく理解できたら
Runnable rをメッセージキューに追加します。ランナブルは、このハンドラがアタッチされているスレッド上で実行されます。
そのため、@ alex2k8が提供する例は、正しく機能していても同じではありません。 Handler.post()
が使用されている場合、 新しいスレッドは作成されません 。 EDT によって実行されるRunnable
を使用して、スレッドにHandler
をポストするだけです。その後、EDTはRunnable.run()
のみを実行し、それ以外は実行しません。
覚えておいてください:Runnable != Thread
。
興味深い例は、カウンタ/ストップウォッチが別のスレッドで継続的に実行されているのを確認できることです。 GPS位置情報も表示します。主な活動の間、ユーザーインターフェーススレッドはすでにそこにあります。
抜粋:
try {
cnt++; scnt++;
now=System.currentTimeMillis();
r=Rand.nextInt(6); r++;
loc=lm.getLastKnownLocation(best);
if(loc!=null) {
lat=loc.getLatitude();
lng=loc.getLongitude();
}
Thread.sleep(100);
handler.sendMessage(handler.obtainMessage());
} catch (InterruptedException e) {
Toast.makeText(this, "Error="+e.toString(), Toast.LENGTH_LONG).show();
}
コードを見るにはここを見てください。
kotlinでは、このようにしてスレッドを実行できます。
class SimpleRunnable: Runnable {
public override fun run() {
println("${Thread.currentThread()} has run.")
}
}
fun main(args: Array<String>) {
val thread = SimpleThread()
thread.start() // Will output: Thread[Thread-0,5,main] has run.
val runnable = SimpleRunnable()
val thread1 = Thread(runnable)
thread1.start() // Will output: Thread[Thread-1,5,main] has run
}
private lateinit var runnable: Runnable
override fun onCreate(savedInstanceState: Bundle?) {
val handler = Handler()
runnable = Runnable {
// do your work
handler.postDelayed(runnable, 2000)
}
handler.postDelayed(runnable, 2000)
}
Runnable runnable;
Handler handler;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
// do your work
handler.postDelayed(this, 1000);
}
};
handler.postDelayed(runnable, 1000);
}