0

I have some foregraund IntentService which could be ran or stopped. I need to reflect its progress(current state which is quite complex) on the Activity if it is visible.

I did not find the reliable and good way to find out whether my IntentService is running and ready to be bound to my Activity.

If I do bindService it always returns true. In case the IntentService is not ran the onServiceConnected(as well as any other callbacks) is never called and my activity remains in the preparation state for always.

The only working solution I found was the static variable in my IntentService class which indicates the service is running. But I believe that is bad practice to use such approach and many people warn it could not work or be unpredictable for some cases.

QUESTION: How do developers of Android expect to handle the failure of bindService call?

And particular case: what to do in case if we are trying to bind to the service which is not running now or in some intermediate state(e.g. shutting down etc).

engilyin
  • 1,011
  • 9
  • 22

1 Answers1

0
    private UploadService.Binder mServiceBinder;

    @Override
        public void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            createService();
        }

    private void createService() {
            if (mServiceBinder == null)
                bindService(new Intent(this, UploadService.class),
                        mConnection,
                        Context.BIND_AUTO_CREATE);
        }

private ServiceConnection mConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mServiceBinder = ((UploadService.Binder) service);
            ((UploadService.Binder) service).getService().setCallback(DashFragment.getInstance());
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceBinder = null;
        }
    };
        @Override
        public void onDestroy() {
            super.onDestroy();
            if (mServiceBinder != null) {
                unbindService(mConnection);
                mServiceBinder = null;
            }
        }

If the mServiceBinder is not null means your service is successfully bounded to the activity else you have to call create service method.

Mahavir Jain
  • 1,448
  • 10
  • 23
  • Wrong solution. First off it means the service is always ran. In my case it could be stopped, run and stop again anytime. Using BIND_AUTO_CREATE is not the case. And does not answer important question what happen if bindService will fail for some reason and onServiceConnected never will be called. That's important to me because I show some preparation UI before the service will be successfully bound and the update for the status will be available. – engilyin Jul 03 '18 at 09:02
  • May be this is not good solution but the service is automatically destroyed once the activity is destroyed because the service is bind with the activity and for your second question when you don't supply a Service or a ServiceConnection listener than only onServiceConnected is never called. – Mahavir Jain Jul 03 '18 at 09:31
  • 1)I prefer do not create the service at all if it is not needed. Creating it just to bind the activity does not look good(e.g. waste of device resources). 2)Why are you sure onServiceConnected always is called? What if service will not be created for some reason (e.g. low on memory etc) Do you know some specs or docs contract which insures that if bindService with BIND_AUTO_CREATE returns true then onServiceConnected will be called in any means? ty – engilyin Jul 03 '18 at 12:28
  • Additionally there is another drawback with BIND_AUTO_CREATE approach if your IntentService is used as foreground service. The notification is not disappears after your onHandleIntent is over. According to the docs while you are having at least one bound activity it will be considered as not done. – engilyin Jul 03 '18 at 15:14