○やりたいこと
Serviceのバックグラウンド挙動を安定させるためActivityとServiceを連携させる
○課題
以下サイトをもとに、ActivityとServiceの連携をおこなっております。
参考サイト
https://qiita.com/satken2/items/49dd76d848ceb208e937
しかし、以下エラーが発生しService起動数秒後にアプリが落ちます。
2021-11-12 23:03:18.165 1720-24063/? E/ActivityManager: ANR in com.example.servicetest PID: 23934 Reason: Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{1ee86ba u0 com.example.servicetest/.MyService}
○教えていただきたいこと
エラーが発生する原因を理解し、改善方法を教えていただきたいです。
MainActivity
1const val MSG_ACTIVITY_TO_SERVICE = 1 2const val MSG_SERVICE_TO_ACTIVITY = 2 3 4class MainActivity : AppCompatActivity() { 5 private var bound = false 6 private var mActivityMessenger: Messenger? = null 7 private var mServiceMessenger: Messenger? = null 8 private var mActivityHandler: ActivityHandler? = null 9 10 private val mConnection = object: ServiceConnection { 11 override fun onServiceConnected(name: ComponentName?, binder: IBinder?) { 12 mServiceMessenger = Messenger(binder) 13 try { 14 val msg = Message.obtain(null, MSG_ACTIVITY_TO_SERVICE, 0, 0) 15 msg.replyTo = mActivityMessenger 16 mServiceMessenger!!.send(msg) 17 } catch (e: RemoteException) { 18 e.printStackTrace() 19 } 20 bound = true 21 } 22 23 override fun onServiceDisconnected(name: ComponentName?) { 24 mServiceMessenger = null 25 bound = false 26 } 27 } 28 29 internal class ActivityHandler( 30 activity: MainActivity 31 ) : Handler() { 32 //define weak reference to activity 33 private val mActivity = WeakReference<MainActivity>(activity) 34 35 override fun handleMessage(msg: Message) { 36 when (msg.what) { 37 MSG_SERVICE_TO_ACTIVITY ->{ 38 //something 39 } 40 else -> super.handleMessage(msg) 41 } 42 } 43 } 44 45 override fun onCreate(savedInstanceState: Bundle?) { 46 Log.d("debug", "onCreate() mainactivity") 47 super.onCreate(savedInstanceState) 48 setContentView(R.layout.activity_main) 49 50 mActivityHandler = ActivityHandler(this) 51 mActivityMessenger = Messenger(mActivityHandler) 52 53 findViewById<Button>(R.id.start).setOnClickListener { 54 Log.d("debug","btnTapped") 55 if(bound) { 56 Log.d("debug", "bound = ture") 57 try { 58 val msg = Message.obtain(null, MSG_ACTIVITY_TO_SERVICE, 0, 0) 59 //val msg = Message.obtain(null, MSG_STOP_UTTERANCE, 0, 0) 60 msg.replyTo = mActivityMessenger 61 mServiceMessenger!!.send(msg) 62 63 intentGo() 64 65 } catch (e: RemoteException) { 66 e.printStackTrace() 67 } 68 } else { 69 Log.d("debug", "bound = false") 70 } 71 } 72 } 73 74 fun intentGo() { 75 Log.d("debug", "intentGo") 76 //start service 77 Intent(this, MyService::class.java).also { 78 Log.d("debug", "Intent") 79 it.action = ACTION_SET_TIMER 80 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 81 Log.d("debug", "startForegroundService") 82 startForegroundService(it) 83 return 84 } 85 startService(it) 86 } 87 } 88 89 override fun onStop() { 90 Log.d("debug", "onStop") 91 super.onStop() 92 //unbind from the service 93 if(bound){ 94 unbindService(mConnection) 95 bound = false 96 } 97 } 98 99 override fun onStart(){ 100 Log.d("debug", "onStart") 101 super.onStart() 102 //bind to the service 103 Intent(this, MyService::class.java).also{ intent -> 104 bindService(intent, mConnection, Context.BIND_AUTO_CREATE) 105 } 106 } 107}
MyService
1class MyService: Service() { 2 private var mServiceMessenger: Messenger? = null 3 4 internal class ServiceHandler( 5 service: MyService 6 ) : Handler() { 7 private val mService = WeakReference<MyService>(service) 8 9 override fun handleMessage(msg: Message) { 10 when (msg.what) { 11 MSG_ACTIVITY_TO_SERVICE ->{ 12 //return some value 13 try { 14 val msg2 = Message.obtain(null, MSG_SERVICE_TO_ACTIVITY, 0, 0) 15 msg.replyTo.send(msg2) 16 } catch (e: RemoteException) { 17 e.printStackTrace() 18 } 19 } 20 else -> super.handleMessage(msg) 21 } 22 } 23 } 24 25 override fun onBind(intent: Intent?): IBinder { 26 Log.d("debug", "onBind") 27 mServiceMessenger = Messenger(ServiceHandler(this)) 28 return mServiceMessenger!!.binder 29 } 30 31 override fun onCreate() { 32 Log.d("debug", "onCreate service") 33 super.onCreate() 34 } 35 36 override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { 37 Log.d("debug", "onStartCommand") 38 39 Thread.sleep(1000) 40 41 val notification = NotificationCompat.Builder(this).apply { 42 var mContentTitle = "通知のタイトル" 43 var mContentText = "通知の内容" 44 setSmallIcon(R.mipmap.ic_launcher) 45 }.build() 46 47 startForeground(0, notification) 48 Log.d("debug", "startForeground") 49 50 return Service.START_NOT_STICKY 51 } 52}
回答1件
あなたの回答
tips
プレビュー