調べてみると、以下のように作るのが一般的?のようだ
1. IntentServiceを継承したクラスを記載
runnableのrunをOverrideし、重い処理を書く
IntentServiceのコンストラクタでHandlerをnewする
IntentServiceのonHandleIntentでhandlerをpostする(これによってUIスレッド側で処理を実施)
一定時間後に繰り返したい場合はpostDelayedで遅延実行
(ThreadSleepを使っても同じようだ)
2. MainActivityで上記Intentを作成、開始 startService で開始
データのやりとりとしては
MainActivity -> IntentService
開始時(startServiceする前)にsetActionで文字列を渡す
IntentService -> MainActivity
MainActivityでBroadcastReceiverを登録しておく
Intentを作成し、putExtraで文字列を登録し、sendBroadcastで送信
---
public class MainActivity extends Activity {
Button buttonStart;
static public TextView textCount;
Intent intent;
boolean isRunning = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonStart = (Button)findViewById(R.id.button_start);
textCount = (TextView)findViewById(R.id.text_count);
// ボタン押下時のハンドラ
buttonStart.setOnClickListener(new ButtonClickListener_startButton()); // 実体は↓のクラス
// Broadcastを受けとるReceiverを設定
DataReceiver dataReceiver = new DataReceiver();
// LocalBroadcastの設定
IntentFilter intentFilter = new IntentFilter("BkTimerEvent");
LocalBroadcastManager.getInstance(this).registerReceiver(dataReceiver, intentFilter);
}
// ボタン押下ハンドラとして登録される
private class ButtonClickListener_startButton implements View.OnClickListener {
@Override
public void onClick(View v){
Log.d("BackgroundTimer", "onClick"); // ログ出力
intent = new Intent(getApplication(), BackgroundIntentTimer.class); // intentを生成
intent.setAction("start"); // 文字列を受け渡す。受け側はonHandleIntentの引数から、getActionで文字列を取得する事ができる(putExtraでも同様の事が出来そう)
startService(intent); // 開始。onHandleIntentが呼び出され
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
// Broadcastを受けとる
public class DataReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent){
Log.d("BackgroundTimer", "MainActivity Received");
// Broadcastされたメッセージを取り出す
String message = intent.getStringExtra("Message");
if(message!=null) {
textCount.setText(message);
}
}
}
}
---
package com.example.training.backgroundtimer;
import android.app.IntentService;
import android.content.Intent;
import android.os.Handler;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
/**
* Timer
*/
public class BackgroundIntentTimer extends IntentService{
private Handler handler;
public BackgroundIntentTimer(){
super("com.example.training.backgroundtimer.BackgroundIntentTimer");
handler = new Handler();
}
@Override
protected void onHandleIntent(Intent intent) {
Log.d("BackgroundTimer", "onHandleIntent");
String action = intent.getAction(); // Activity側でsetActionした内容を出力
// callbackをremoveしないと重複処理される為
handler.removeCallbacks(thread);
if(action.equals("start")){
count = 0;
handler.post(thread); // UIスレッドに対して処理をポストする(描画処理の為)
}
Log.d("BackgroundTimer", action);
}
// スレッド
private Runnable thread = new Runnable() {
@Override
public void run() {
// ここに重い処理を呼び出す
Log.d("BackgroundTimer", "run!!");
timerProcess();
}
};
private void timerProcess(){
// 表示更新用にメッセージ(Intent)送信
Log.d("BackgrountTimer", "timer Process"); Intent messageIntent = new Intent("BkTimerEvent");
messageIntent.putExtra("Message", Integer.toString(count));
LocalBroadcastManager.getInstance(this).sendBroadcast((messageIntent));
// 1秒ごとにカウントアップする処理
/*
try {
LocalBroadcastManager.getInstance(this).sendBroadcast((messageIntent)); handler.removeCallbacks(thread);
Thread.sleep(1000);
} catch (InterruptedException ie){
Log.d("BackgroundTimer", "timer error");
}
*/
handler.removeCallbacks(thread); handler.postDelayed(thread,1000); // 遅延実行する場合
// handler.post(thread); //Thread.sleepする場合
}
}
}