카테고리 없음

[android] Android java.lang.IllegalArgumentException : 서비스가 등록되지 않았습니다.

행복을전해요 2021. 2. 23. 20:36

I realize this question has already been answered. But I think there is reason to go into why people are making this mistake.

The issue is really with the training docs. http://developer.android.com/reference/android/app/Service.html shows a correct implementation while https://developer.android.com/guide/components/bound-services.html in the 'ActivityMessenger' shows a Very INCORRECT implementation.

In the 'ActivityMessenger' example onStop() could potentially be called before the service has actually been bound.

The reason for this confusion is they are using the bound service boolean to mean different things in different examples. (mainly, was bindService() called OR is the Service actually connected)

In the correct examples where unbind() is done based on the value of the bound boolean, the bound boolean indicates that the bindService() was called. Since it's queued up for main thread execution, then unbindService() needs to be called (so queued to be executed), regardless of when (if ever) onServiceConnected() happens.

In other examples, such as the one in http://developer.android.com/reference/android/app/Service.html. The bound indicates that the Services is Actually bound so that you can use it and not get a NullPointerException. Note that in this example, the unbindService() call is still made and the bound boolean doesn't determine whether to unbind or not.

-------------------

Use mIsBound inside doBindService() and doUnbindService() instead of in the ServiceConnection instance.

ServiceConnection mConnection = new ServiceConnection() {
    @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
                mBinder = (MyIBinder) service;
                    }
                    
                        @Override
                            public void onServiceDisconnected(ComponentName name) {
                                    mBinder = null;
                                        }
                                        }; 
                                        
                                        ...
                                        
                                        public void doBindService() {
                                            bindService(new Intent(this, MyService.class),
                                                    mConnection, Context.BIND_AUTO_CREATE);
                                                        mIsBound = true;
                                                        }
                                                        
                                                        public void doUnbindService() {
                                                            if (mIsBound) {
                                                                    unbindService(mConnection);
                                                                            mIsBound = false;
                                                                                }
                                                                                }
                                                                                

This is how it's done in http://developer.android.com/reference/android/app/Service.html

-------------------

java.lang.IllegalArgumentException: Service not registered means that you weren't bound to service when unbindService() was called.

So in your case, onSomeEvent() was never called before call to unbindService() in onPause()

-------------------

이 예외의 또 다른 가능한 이유 unbindService는 잘못된 호출 일 수 있습니다 Context. 서비스는 활동뿐 아니라 Context다른 서비스에 의해 상속 된 다른 인스턴스 (BroadcastReceivers 제외)에 의해서도 unbindService바인딩 Service될 수 있으므로 바인딩 Service자체가 아닌 바인딩 된 컨텍스트에 의해 호출되어야합니다 . 이 경우 위의 예외 "서비스가 등록되지 않음"이 직접 발생합니다.

-------------------

이유?

Activity에서 unbindService ()가 bindService () 전에 호출되면 this IllegalArgumentException.

그것을 피하는 방법?
간단 해. 이 순서로 서비스를 바인드 및 바인드 해제하면 부울 플래그가 필요하지 않습니다.

해결책 1 :

바인딩 onStart()및 바인딩 해제onStop()

Your Activity {

    @Override
        public void onStart()
            {
                    super.onStart();
                            bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
                                }
                                
                                    @Override
                                        public void onStop()
                                            {
                                                    super.onStop();
                                                            unbindService(mConnection);
                                                                }
                                                                
                                                                 } 
                                                                 

해결 방법 2 :
바인딩 onCreate()및 바인딩 해제onDestroy()

 Your Activity {

    @Override
        public void onCreate(Bindle sis)
            {
                    super.onCreate(sis);
                            ....
                                    bindService(intent, mConnection , Context.BIND_AUTO_CREATE);
                                        }
                                        
                                            @Override
                                                public void onDestroy()
                                                    {
                                                            super.onDestroy();
                                                                    unbindService(mConnection);
                                                                        }         
                                                                        
                                                                         }
                                                                         

관련 링크 :

안드로이드 공식 문서가 제안 하는 것이
이 서비스와 상호 작용이 필요한 경우 활동이있는 동안 만 볼 수 다음으로 이동 Solution1 . 백그라운드
에서 중지 된 상태에서도 활동이 응답을 받도록하려면 Solution2 로 이동하십시오 .

-------------------

제 경우에는 bindService를 사용하여 호출 Activity Context하고 ApplicationContext. 하지마.

-------------------

내 응용 프로그램과 똑같은 문제가 있습니다. 때때로 나는 IllegalArgumentException. 서비스가 바인딩 해제되고 이전onPause 에 호출 될 때 특별한 경우가 발생한다고 생각합니다 . 그래서 나는 올바른 실행을 보장하기 위해 노력할 것입니다. onServiceDisconnectedSynchronized

-------------------
class ServiceBindManager<T>(val context: Context, clazz: Class<T>) {

    val TAG: String = "ServiceBindManager"
    
        private val isBound: AtomicBoolean = AtomicBoolean(false)
        
            private var intent: Intent = Intent(context, clazz)
            
                private val connection: ServiceConnection = object : ServiceConnection {
                        override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
                                    Log.d(TAG, "onServiceConnected: $context")
                                                isBound.set(true)
                                                        }
                                                        
                                                                override fun onServiceDisconnected(name: ComponentName?) {
                                                                            Log.d(TAG, "onServiceDisconnected: $context")
                                                                                        isBound.set(false)
                                                                                                }
                                                                                                
                                                                                                        override fun onBindingDied(name: ComponentName?) {
                                                                                                                    isBound.set(false)
                                                                                                                            }
                                                                                                                            
                                                                                                                                    override fun onNullBinding(name: ComponentName?) {
                                                                                                                                                isBound.set(false)
                                                                                                                                                        }
                                                                                                                                                            }
                                                                                                                                                            
                                                                                                                                                            
                                                                                                                                                                 fun bindService() {
                                                                                                                                                                         Log.e(TAG, "bindService: $context")
                                                                                                                                                                                 isBound.set(context.bindService(intent, connection, BIND_AUTO_CREATE))
                                                                                                                                                                                     }
                                                                                                                                                                                     
                                                                                                                                                                                          fun unbindService() {
                                                                                                                                                                                                  Log.e(TAG, "unbindService: $context")
                                                                                                                                                                                                          if (isBound.get()) {
                                                                                                                                                                                                                      isBound.set(false)
                                                                                                                                                                                                                                  context.unbindService(connection)
                                                                                                                                                                                                                                          }
                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                              }
                                                                                                                                                                                                                                              
                                                                                                                                                                                                                                              

용법:


override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
                serviceBindManager = ServiceBindManager(this@MyActivity, MyService::class.java)
                }
                
                 override fun onStart() {
                         super.onStart()
                                 serviceBindManager.bindService()
                                 }
                                 
                                  override fun onStop() {
                                          super.onStop()
                                                  serviceBindManager.unbindService()
                                                  }
                                                  


출처
https://stackoverflow.com/questions/22080054