Androidのスレッドを解説(サンプルコード編)

前回 (前回のページ) は、Androidのスレッド構造について書いた。

 今回は、スレッドに関するサンプルコードを幾つかご紹介する。

 

■サンプル1 (RunnableをpostDelayed()する例)

 まず最初は、画面にButtonとTextViewがあり、TextViewには"0"と書かれている。

ボタンをタップすると、1,2,3・・・と、タラ~っと数字が動いていき、10000まで表示したら終了というものを作ってみる。タラ~っという「動き」を見せたいのであれば、postする単位(Runnableの処理内容)を1コマ分の動きにして、それを10000回postすることで、10000回の描画をさせる。

 

public class MainActivity extends AppCompatActivity {
TextView txt1;
Button btn1;
Handler handler;

@Override
protected void onCreate(Bundle savedInstanceState) { //このCallBackは、メインスレッドで呼ばれる!
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

handler = new Handler(); //MainスレッドでHandlerを作成!
btn1 = (Button) findViewById(R.id.button1);
txt1 = (TextView) findViewById(R.id.text1);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //クリックされた場合
new Thread() { //メインスレッドで重い処理をしないよう、サブスレッドを作成。
public void run() { //スレッドをstart()すると、ここがサブスレッドとして実行される。
for (int i = 0; i < 10000; i++) { //1万回ループ
handler.postDelayed( //メインスレッドのMessage Queueに格納するための
new Runnable() { //Runnableを作成する
@Override
public void run() { //このrunメソッドをメインスレッドのLooperにCallしてもらう
int now = Integer.parseInt(txt1.getText().toString()); //現状の値に
txt1.setText(Integer.toString(now + 1)); //1加算する
}
}, i); //実行までの遅延時間を iミリ秒後に設定
} //end of for
} // end of run()
}.start(); //作成したスレッドを起動!
}
});
}
}

 

 

■サンプル2 (MessageをsendMessageDelayed()する例)

 サンプル1のコードを、sendMessageDelayed()を使って書き直す。

 

public class MainActivity extends AppCompatActivity {
TextView txt1;
Button btn1;

static class MyHandler extends android.os.Handler {
private TextView tv;

MyHandler(TextView tv) {
this.tv = tv;
}

@Override
public void handleMessage(Message msg) {
if (msg.what == 10) { //要求種別を適当に10とする
int now = Integer.parseInt(tv.getText().toString()); //現状の値に
String counter = Integer.toString(now + 1); //1加算する
tv.setText(counter); //Viewにセット
}
}
}

@Override
protected void onCreate(Bundle savedInstanceState) { //このCallBackは、メインスレッドで呼ばれる!
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

btn1 = (Button) findViewById(R.id.button1);
txt1 = (TextView) findViewById(R.id.text1);
final MyHandler handler = new MyHandler(txt1);

btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { //クリックされた場合
new Thread() { //メインスレッドで重い処理をしないよう、サブスレッドを作成。
public void run() { //スレッドをstart()すると、ここがサブスレッドとして実行される。
for (int i = 0; i < 10000; i++) { //1万回ループ
Message msg = handler.obtainMessage(10); //Messageを作成。要求種別を適当に10とする
//メインスレッドのMessage QueueにMessageを格納する(遅延時間は iミリ秒)
handler.sendMessageDelayed(msg, i);
}
}
}.start(); //作成したスレッドを起動!
}
});
}
}

 

■サンプル3(Delayed系メソッドを使わない方法でもやってみよう)

サンプル2と違う部分のみ掲載する。xxxxxxxDelayed()系のメソッドを使う代わりに自力でsleepする。特に要求種別(10)以外に送るものがないので、obtain()も省略してsendEmptyMessage()のみにしてみる。

 

public void run() {     //スレッドをstart()すると、ここがサブスレッドとして実行される。
for (int i = 0; i < 10000; i++) { //1万回ループ
handler.sendEmptyMessage(10); //メインスレッドのMessage QueueにMessageを格納する
try {
Thread.sleep(1);  // 1ミリ秒sleep
} catch (Exception e) {}
}
}

 

しかし、Androidの内部ソースを見てみたところ、sendEmptyMessage(int)を発行しても、結局すぐにDelayを呼ぶし、obtain()もしていたw

public final boolean sendEmptyMessage(int what)
{
return sendEmptyMessageDelayed(what, 0);
}

public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
Message msg = Message.obtain();
msg.what = what;
return sendMessageDelayed(msg, delayMillis);
}

 

  

---------------------------------------------------

ITとことん の目次
┗■Androidの調査結果(目次)
 ┗■本ページ