Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Service can be bind without start?

In many articles, tutorials, docs, have read so far, that we call startService() or bindService(), both starts the service. We can call both also, but that's a different story. I am unable to bindService without startService().

    private void bindTunManagerService(int flags) {
    TunnelManagerService.setParentActivity(this);
    Intent bindIntent = new Intent(this, TunnelManagerService.class);
    startService(bindIntent);
    tunManagerServiceStarted = bindService(bindIntent, tunConnection, BIND_AUTO_CREATE);

    Log.d(TAG, "tunManagerServiceStarted  : " + tunManagerServiceStarted + ", ** tunManagerService = " + tunManagerService );

In the above code, if I comment startService(), bindService returns false and tunManagerService = null, even onServiceConnected is not fired up and I get "Unable to sart service intent {...} not found" message. After adding startService, service's onCreate, onStart, onServiceConnected are called and is successfully bounded.

In practical usage, is it necesary to first startServie & then only we can bindService(). It implies that without startSErvice, we can't bindService !! If this statement is wrong, why I can't bindService without starting it ?

Any ideas ????

CODE ADDED

ServiceConnection :

    private ServiceConnection tunConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.d(TAG,"onServiceConnected" );
        tunManagerService = ITunnelManagerService.Stub.asInterface(service);
        doConnect();
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d(TAG,"onServiceDisconnected" );
        tunManagerService = null;
    }

};

Service :

public class TunnelManagerService extends Service {
@Override
public IBinder onBind(Intent arg0) {
    return binder;
}

@Override
public void onCreate() {
    super.onCreate();
    Log.d(TAG, "TunnelManagerService: onCreate");
    setCreatedPreference(true);
    notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.i(TAG, "Received start id " + startId + ": " + intent);
    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    setCreatedPreference(false);
    hideNotifConnected();
    Log.d(TAG, "TunnelManagerService: onDestroy");
}

private final ITunnelManagerService.Stub binder = new ITunnelManagerService.Stub() {
  // contains all methods
}

...............
.............

}

Manifest :

        <activity android:name=".StartUltimate" android:label="@string/app_name" 
         android:launchMode="singleTask" android:windowSoftInputMode="stateHidden|adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <service android:name="orange.android.vpn.utilities.TunnelManagerService" android:enabled="true"></service>

I use 2.3.3 SDK i.e. API 10. My activity from which I am calling is in "orange.android.vpn" and the service related files are in "orange.android.vpn.utilities" packages respectively.

like image 515
Tvd Avatar asked Apr 28 '11 13:04

Tvd


2 Answers

I found the solution, so am sharing with all of you.

There are 2 types of Services : One where you start and stop. This can be started and stopped only once in an application. Other you Bind and Unbind as required N number of times. My Service is of second type. But just bind and unbind doesn't do the job. The service first needs to be started then only it cna be bound and unbound. So on start of app or whereever appropriate, Start the service. Then Bind when required. When don with it, Unbind it. That Bind-Unbind circle can go on. And Finally when you are sure you don't need it or at the end of the app Stop the Service. So the flow comes as Start -> Bind -> Unbind -> Stop <-

Hope this helps someone.

like image 50
Tvd Avatar answered Oct 18 '22 03:10

Tvd


Yes.

bindService(new Intent(this, MyService.class), mConnection, 0);

AFAIK, this will always return true (assuming there is no problem with MyService)

There are two scenarios:

  1. The service has previously been started - mConnection's onServiceConnected() is called
  2. The service has NOT previously been started - mConnection's onServiceConnected() is NOT called and the service is NOT started. However, as soon as the service is started (by some other means), the onServiceConnected() is then called

In practice, when I call this method, I assume the service is not started until the onServiceConnected() method is called.

like image 38
Mark Avatar answered Oct 18 '22 02:10

Mark