Xamarin タイマーで表示を定期更新
タイマーを使ってみる単純な例として、0.5秒ごとに数を加算して表示するプログラムを作ってみます。
xamarin で使えるタイマーのクラスには何種類かあるようなのですが、System.Timers.timer クラスが簡単に使えそうだったので、これを使うことにします。
まず、文字を表示するために TextView を一つ貼りつけたアクティビティを作成しておきます。(やり方は Xamarin でとても簡単な android アプリを作る なんかを参照)
コードはこんな感じ。
下のように書いても同じ。
実行してみた様子。ちゃんと 0.5秒毎に数が増えて、表示されます。
ポイントは
ここを普通に
自分もよくわかっていないのですが、そういう事のようです(笑)。
xamarin で使えるタイマーのクラスには何種類かあるようなのですが、System.Timers.timer クラスが簡単に使えそうだったので、これを使うことにします。
まず、文字を表示するために TextView を一つ貼りつけたアクティビティを作成しておきます。(やり方は Xamarin でとても簡単な android アプリを作る なんかを参照)
コードはこんな感じ。
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Timers; // タイマーを使うので追加
namespace timer2
{
[Activity (Label = "timer2", MainLauncher = true)]
public class Activity1 : Activity
{
int count = 1;
private System.Timers.Timer timer1;
private TextView text1;
Handler mHandler = new Handler ();
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
text1 = FindViewById<TextView> (Resource.Id.textView1);
text1.TextSize = 64; // さみしいので字を大きく
timer1 = new System.Timers.Timer ();
timer1.Enabled = true;
timer1.AutoReset = true; // 繰り返し
timer1.Interval = 500; // 500ms
timer1.Elapsed += new ElapsedEventHandler (OnTimerEvent);
timer1.Start (); // タイマースタート
}
private void OnTimerEvent(object source, ElapsedEventArgs e)
{
count++;
mHandler.Post (delegate {
text1.Text = count.ToString ();
});
}
}
}
けっこう簡単に書けました。下のように書いても同じ。
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Timers; // タイマーを使うので追加
namespace timer2
{
[Activity (Label = "timer2", MainLauncher = true)]
public class Activity1 : Activity
{
int count = 1;
private System.Timers.Timer timer1;
private TextView text1;
Handler mHandler = new Handler ();
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
text1 = FindViewById<textview> (Resource.Id.textView1);
text1.TextSize = 64; // さみしいので字を大きく
timer1 = new System.Timers.Timer ();
timer1.Enabled = true;
timer1.AutoReset = true; // 繰り返し
timer1.Interval = 500; // 500ms
timer1.Elapsed += delegate {
count++;
mHandler.Post (delegate {
text1.Text = count.ToString ();
});
};
timer1.Start (); // タイマースタート
}
}
}
実行してみた様子。ちゃんと 0.5秒毎に数が増えて、表示されます。
ポイントは
mHandler.Post (delegate {
text1.Text = count.ToString ();
});
の所。ここでタイマーイベントで起動したスレッドから、メインのスレッドに Text を更新してもらうようにお願いしています。ここを普通に
text1.Text = count.ToString ();
と書くと、メインのスレッドとは別のスレッドから text を更新する事になって表示が更新されません。自分もよくわかっていないのですが、そういう事のようです(笑)。