最初の質問: そのアプローチは正しいですか?
Runnable
いいえ、 s in Thread
s in aを実装して実行する必要がありますService
。
複数のリクエストを同時に処理するIntentService
必要がない場合は、 が最適なオプションです。Service
を起動すると、起動した がバックグラウンドに移動したり停止したりしてService
も、バックグラウンドで実行され続けます。Activity
は、UIのRunnable
更新が必要であることを示すブロードキャストを送信できます。はActivity
を登録BroadcastReceiver
してブロードキャスト メッセージをリッスンし、それに応じて UI を更新する必要があります。
を使用して、AlarmManager
指定したとおりにジョブの実行をスケジュールできます。 これを行う 1 つの方法は、適切なジョブを実行することによって動作するAlarmManager
、ブロードキャストを送信して が受信するようにスケジュールすることです。IntentService
これらすべてを組み合わせた例を次に示します。
こちらがIntentService
public class MyIntentService extends IntentService {
public static final String ACTION_START_JOB = "com.mycompany.myapplication.START_JOB";
public static final String ACTION_UPDATE_UI = "com.mycompany.myapplication.UPDATE_UI";
private final IBinder mBinder = new MyBinder();
// You can have as many Runnables as you want.
Runnable run = new Runnable() {
@Override
public void run() {
// Code to run in this Runnable.
// If the code needs to notify an Activity
// for a UI update, it will send a broadcast.
Intent intent = new Intent(ACTION_UPDATE_UI);
sendBroadcast(intent);
}
};
public MyIntentService() {
super("MyIntentService");
}
@Override
public void onCreate() {
// You need to register your BroadcastReceiver to listen
// to broadcasts made by the AlarmManager.
// The BroadcastReceiver will fire up your jobs when these
// broadcasts are received.
IntentFilter filter = new IntentFilter(ACTION_START_JOB);
registerReceiver(jobBroadcastReceiver, filter);
}
@Override
public void onDestroy() {
// You should unregister the BroadcastReceiver when
// the Service is destroyed because it's not needed
// any more.
unregisterReceiver(jobBroadcastReceiver);
}
/**
* This method is called every time you start this service from your
* Activity. You can Spawn as many threads with Runnables as you want here.
* Keep in mind that your system have limited resources though.
*/
@Override
protected void onHandleIntent(Intent intent) {
Intent intentFireUp = new Intent();
intentFireUp.setAction(ACTION_START_JOB);
PendingIntent pendingIntentFireUpRecording = PendingIntent
.getBroadcast(MyIntentService.this, 0, intentFireUp, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Calendar cal = Calendar.getInstance();
int year = 2013, month = 5, day = 10, hourOfDay = 7, minute = 13, second = 0;
cal.set(year, month, day, hourOfDay, minute, second);
long startTime = cal.getTimeInMillis() + 5 * 60 * 1000; // starts 5
// minutes from
// now
long intervalMillis = 24 * 60 * 60 * 1000; // Repeat interval is 24
// hours (in milliseconds)
// This alarm will send a broadcast with the ACTION_START_JOB action
// daily
// starting at the given date above.
alarm.setRepeating(AlarmManager.RTC_WAKEUP, startTime, intervalMillis,
pendingIntentFireUpRecording);
// Here we spawn one Thread with a Runnable.
// You can spawn as many threads as you want.
// Don't overload your system though.
new Thread(run).run();
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// Depending on your implementation, you may need to bind
// to this Service to run one of its methods or access
// some of its fields. In that case, you will need a Binder
// like this one.
public class MyBinder extends Binder {
MyIntentService getService() {
return MyIntentService.this;
}
}
// Spawns a Thread with Runnable run when a broadcast message is received.
// You may need different BroadcastReceivers that fire up different jobs.
BroadcastReceiver jobBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
new Thread(run).run();
}
};
}
そして、これがActivity
public class MyActivity extends Activity {
Service mService;
boolean mBound = false;
ToggleButton mButton;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mButton = (ToggleButton) findViewById(R.id.recordStartStop);
mButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
if (mButton.isChecked()) {
Intent intent = new Intent(MyActivity.this,
MyIntentService.class);
startService(intent);
}
}
});
}
@Override
protected void onStart() {
super.onStart();
}
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(MyIntentService.ACTION_UPDATE_UI);
registerReceiver(uiUpdateBroadcastReceiver, filter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(uiUpdateBroadcastReceiver);
}
BroadcastReceiver uiUpdateBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// Here goes the code to update your User Interface
}
};
ServiceConnection myServiceConnection = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
mBound = false;
}
// If you need
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MyIntentService mService = ((MyBinder) service).getService();
mBound = true;
}
};
}
ファイルにService
定義を追加することを忘れないでください。AndroidManifest.xml
<manifest ... >
...
<application ... >
<service android:name=".MyIntentService" />
...
</application>
</manifest>