62

次のようなセットアップがあります。

class MyFragment implements SomeEventListener {

    Application mAppContext;    

    boolean mBound;
    boolean mDidCallUnbind;
    MyIBinder mBinder;
    ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mBound = true;
            mBinder = (MyIBinder) service;
            mBinder.getThings();...
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mDidCallUnbind = false;
            mBound = false;
            mBinder = null;
        }
    };

    ...

    @Override
    public void onSomeEvent() {
        mAppContext.bindService(...);
    }

    void unbindService() {
        if (mBound && !mDidCallUnbind) {
            mDidCallUnbind = true;
            mAppContext.unbindService(mConnection);
        }
    }

    @Override
    public void onPause() {
        unbindService();
        super.onPause();
    }
}

ただし、タイトルに時々エラーが表示されます:が呼び出されjava.lang.IllegalArgumentException: Service not registeredたときに生成されます。unbindService()私はばかげたことを見逃していますか、それとももっと起こっていますか? この同じフラグメントが複数存在する可能性があることに注意してください。

編集

誰も実際にコードを読んでいないように見えるので、説明させてください。 は、サービスがバインド ( )さていて、コールバックが への以前の呼び出しの可能性からヒットする前に呼び出されていない限り、unbindService()呼び出されません。 Context.unbindService(ServiceConnection)mBoundonServiceDisconnected(...)unbindService()

そのことを念頭に置いて、サービスがアンバインドされるように Android がサービスのバインドを解除するが、onServiceDisconnected が呼び出されないため、古い状態のままになる場合はありますか?

また、アプリケーション コンテキストを使用して初期バインディングを行っています。次のようなものと仮定します。

@Override
public void onCreate() {
    mApplication = getContext().getApplicationContext();
}
4

8 に答える 8

33

mIsBoundインスタンスの内側doBindService()doUnbindService()代わりに使用しServiceConnectionます。

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() {
    mIsBound =bindService(new Intent(this, MyService.class),
        mConnection, Context.BIND_AUTO_CREATE); 
}

public void doUnbindService() {
    if (mIsBound) {
        unbindService(mConnection);
        mIsBound = false;
    }
}

これはhttp://developer.android.com/reference/android/app/Service.htmlでの方法です

于 2015-09-10T18:09:39.820 に答える
8

java.lang.IllegalArgumentException: Service not registeredunbindService()が呼び出されたときにサービスに拘束されていなかったことを意味します。

したがって、あなたの場合、 inへのonSomeEvent()呼び出しの前に呼び出されたことはありませんunbindService()onPause()

于 2014-02-27T20:49:48.677 に答える
0
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()
}
于 2019-09-09T12:29:12.513 に答える