インテントサービスは停止するまでバックグラウンドで動き続ける通常のサービスと違い、処理が終わると「自動終了」してくれるので、いちいちサービスを停止させるコードを書く必要がありません。使い道はいろいろありますが、特にバックグラウンドでダウンロードさせる場合に最適なサービスだといえるでしょう。
<もくじ>
1.インテントサービスを使用する時の注意点
インテントサービスの使い方は通常のサービスとほぼ同じですが、空のコンストラクターが必要になるので、以下の例のようなコンストラクターを必ずインテントサービス内に追加してください。これがないとマニフェストファイルにインテントサービスを追加した時のエラーが消えません。
//空のコンストラクターが必要
public MyIntentService() {
super(null);
}
もう一つ注意点があります。それは、インテントサービス内に「onHandleIntent」というオーバーライドメソッドを追加すると、引数部分にエラーの元になる「@androidx.annotation.Nullable」という文字が追加されるところです。これがあるとエラーが消えませんので、以下のように手動で削除してください。
@Override
protected void onHandleIntent(@androidx.annotation.Nullable Intent intent) {
↓↓↓ 赤字の部分を削除するとエラーは消える ↓↓↓
@Override
protected void onHandleIntent(Intent intent) {
本来は必要な文字列だとは思いますが、とりあえず削除すれば動くようになります。
2.サンプルコード
インテントサービスに必要なコードです。
2.1 サンプルコード①(MainActivity.java)
メインは、ボタンが押されるとインテントサービスにインテントを送信するだけの簡単な内容です。詳しい説明はコード内のコメントを参照してください。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//レイアウトファイルをビューにセット
setContentView(R.layout.activity_main);
//レイアウトファイルのボタンを取得してインスタンス化
Button button = (Button)findViewById(R.id.button);
//取得したボタンにクリックイベントをセット
button.setOnClickListener(new View.OnClickListener() {
//ボタンがクリックされた時の処理
@Override
public void onClick(View v) {
//起動するサービス名を登録したインテントを生成
Intent intent = new Intent(getBaseContext(),MyIntentService.class);
//インテントにアクションを追加セット
intent.setAction("TEST");
//インテントを送ってサービスを開始する
getBaseContext().startService(intent);
}
});
}
}
2.2 サンプルコード②(MyIntentService.java)
インテントサービスのコードです。空のコンストラクターを必ず追記します。
流れは、インテントを受け取ると10秒間隔の繰り返し処理が開始され、それを5回繰り返したところで、処理が終了するようになっています。
インテントサービスなので、サービスの停止処理はありません。
public class MyIntentService extends IntentService {
public MyIntentService(String name) {
super(name);
}
//空のコンストラクターが必要
public MyIntentService() {
super(null);
}
boolean hantei = true; //処理回数判定用
int kaisu = 0; //処理回数のカウント用
//インテントを受信した時に実行される
@Override
protected void onHandleIntent(Intent intent) {
//ログに出力
Log.d("TEST--->","「" + intent.getAction() + "」を受信");
//処理内容
new Thread(new Runnable() {
@Override
public void run() {
//ログに出力
Log.d("TEST--->","処理を開始します");
//繰り返し処理
while (hantei) {
//カウントアップ
kaisu += 1;
//ログに出力
Log.d("TEST--->",kaisu + "");
//カウントアップの終了判定(5回で終了)
if(kaisu >= 5) {
//フラグを「false」にして終了させる
hantei = false;
}
//10秒間隔で処理を実行させるためにスリープさせている
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//ログに出力
Log.d("TEST--->","処理が終了しました");
}
}).start();
}
}
2.3 サンプルコード③(AndroidManifest.xml)
マニフェストファイルにはインテントサービスを追加で登録してください。これを忘れるとプログラムがあっても正しく動きません。
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- インテントサービスを登録する -->
<service android:name=".MyIntentService" />
</application>
2.4 サンプルコード④(main_activity.xml)
レイアウトは画面の中央に「Button」があるだけの単純なものです。
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<起動画面>
3.結果
画面中央に配置したボタンをクリックすると、インテントサービスが起動して10秒間隔でカウントアップする処理が開始され、5回繰り返すと処理をが終わりインテントサービスも終了します。処理の状況はアンドロイドスタジオのログ画面に表示されます。
実行中にバックグラウンドプロセスを確認すると、インテントサービスが動いているのを確認することができます。
4.まとめ
インテントサービスは停止処理を書く必要がなく通常のサービスより気軽に使用できますが、公式開発サイトでは、サービスは「Android 8.0(APIレベル26)」から課せられている「バックグラウンド実行制限」の影響を受けるため「JobIntentService」を使用する方が賢明だとしていますので、より多くの端末をターゲットにしなければならない場合は、APIレベルで処理を振り分ける必要がありそうです。
公式開発サイト<インテントサービス>
END