では、AndroidStudioを使ってServiceを追加してみよう。
特に何かしたいわけでもないので、毎分logcatで何か出し続けるようにしてみる。そうすればいつアプリが終了させられたのかもわかりやすいんじゃなかろうか。
デフォルトをちょっと変更したプロジェクトの設定はこんな感じ。
家にあるAndroid端末で一番古いのがNougatなので、Min SDK Versionはこの辺にしている。
プロジェクトを新規作成して取りあえずビルドしてみたのだが、トップディレクトリにあるbuild.gradleのjcenter()でwarningが出ていた。
JCenter サービスの更新 | Android デベロッパー | Android Developers
https://developer.android.com/studio/build/jcenter-migration
既存のものは無期限にダウンロードできます、といっても「閉鎖されるまでは」という条件が付くだろう。メンテナンスしないとしても電気代はかかるし、自社サーバだったらストレージが故障したりするし、クラウドだったらストレージの費用も馬鹿にならんし。
Serviceを追加する!と気合いを入れずとも、AndroidStudioならメニュー操作で基本的なところはやってくれそうだ。
2つある・・・?
"Service"の場合
"Service(IntentService)"の場合
ちなみにActivityのあるディレクトリ?以外で実行するとどこに組み込むかのコンボボックスが増えていた。
main, debug, releaseの3択だったのだが、特定のVariantにだけ追加する(debug, release)か、全部に追加する(main)かを選んでいるのだろうか。
Build Variantsを追加すると増えていたので、たぶんそうなんだろう。
まずは、ただのServiceを追加した場合。
ファイルの追加
app\src\main\java\com\example\sample0\MyService.kt
01: package com.example.sample0 02: 03: import android.app.Service 04: import android.content.Intent 05: import android.os.IBinder 06: 07: class MyService : Service() { 08: 09: override fun onBind(intent: Intent): IBinder { 10: TODO("Return the communication channel to the service.") 11: } 12: }
AndroidManifest.xmlに追記。
01: <service 02: android:name=".MyService" 03: android:enabled="true" 04: android:exported="true"></service>
こちらはIntentServiceを追加した場合。
ファイルの追加
app/src/main/java/com/example/sample0/MyIntentService.kt
01: package com.example.sample0 02: 03: import android.app.IntentService 04: import android.content.Intent 05: import android.content.Context 06: 07: // TODO: Rename actions, choose action names that describe tasks that this 08: // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS 09: private const val ACTION_FOO = "com.example.sample0.action.FOO" 10: private const val ACTION_BAZ = "com.example.sample0.action.BAZ" 11: 12: // TODO: Rename parameters 13: private const val EXTRA_PARAM1 = "com.example.sample0.extra.PARAM1" 14: private const val EXTRA_PARAM2 = "com.example.sample0.extra.PARAM2" 15: 16: /** 17: * An [IntentService] subclass for handling asynchronous task requests in 18: * a service on a separate handler thread. 19: 20: * TODO: Customize class - update intent actions, extra parameters and static 21: * helper methods. 22: 23: */ 24: class MyIntentService : IntentService("MyIntentService") { 25: 26: override fun onHandleIntent(intent: Intent?) { 27: when (intent?.action) { 28: ACTION_FOO -> { 29: val param1 = intent.getStringExtra(EXTRA_PARAM1) 30: val param2 = intent.getStringExtra(EXTRA_PARAM2) 31: handleActionFoo(param1, param2) 32: } 33: ACTION_BAZ -> { 34: val param1 = intent.getStringExtra(EXTRA_PARAM1) 35: val param2 = intent.getStringExtra(EXTRA_PARAM2) 36: handleActionBaz(param1, param2) 37: } 38: } 39: } 40: 41: /** 42: * Handle action Foo in the provided background thread with the provided 43: * parameters. 44: */ 45: private fun handleActionFoo(param1: String?, param2: String?) { 46: TODO("Handle action Foo") 47: } 48: 49: /** 50: * Handle action Baz in the provided background thread with the provided 51: * parameters. 52: */ 53: private fun handleActionBaz(param1: String?, param2: String?) { 54: TODO("Handle action Baz") 55: } 56: 57: companion object { 58: /** 59: * Starts this service to perform action Foo with the given parameters. If 60: * the service is already performing a task this action will be queued. 61: * 62: * @see IntentService 63: */ 64: // TODO: Customize helper method 65: @JvmStatic 66: fun startActionFoo(context: Context, param1: String, param2: String) { 67: val intent = Intent(context, MyIntentService::class.java).apply { 68: action = ACTION_FOO 69: putExtra(EXTRA_PARAM1, param1) 70: putExtra(EXTRA_PARAM2, param2) 71: } 72: context.startService(intent) 73: } 74: 75: /** 76: * Starts this service to perform action Baz with the given parameters. If 77: * the service is already performing a task this action will be queued. 78: * 79: * @see IntentService 80: */ 81: // TODO: Customize helper method 82: @JvmStatic 83: fun startActionBaz(context: Context, param1: String, param2: String) { 84: val intent = Intent(context, MyIntentService::class.java).apply { 85: action = ACTION_BAZ 86: putExtra(EXTRA_PARAM1, param1) 87: putExtra(EXTRA_PARAM2, param2) 88: } 89: context.startService(intent) 90: } 91: } 92: }
AndroidManifest.xmlに追記。
01: <service 02: android:name=".MyIntentService" 03: android:exported="false"></service>
なぜか知らんが、AndroidManifest.xmlはさっき追記した <service ...></service> が <service ... /> に置き換えられた。
名前に同じ「Service」が付いているものの、全然似たところがない。
だがIntentServiceはServiceの派生クラスだ。
と思ったら! IntentServiceはAPI 30からdeprecatedとのことだ。代わりに androidx.work.WorkManager とか androidx.core.app.JobIntentService を使うことをおすすめされている。
WorkManager はバックグラウンドタスクのところに出ていた。 JobIntentService は「作業ステータスを報告する」に出てきていた。
一つ分かったのは、初学者にとってはclassから調べていくのは効率が悪そうだ、ということだ。「人間とは何か」を調べる命題があったとして、細胞とか動植物から調べ始めるようなもので、間違っているわけではないけど後で調べた方が効率がよさそう、というやつだ。
そして・・・私はIntentServiceは忘れることにした。
私のバッファはそんなに大きくないのだ。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。