0

I have a function in a service as follows:

public class ServiceA extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_NOT_STICKY;
    }

    private final IBinder mBinder = new LocalBinder();

    public void readFunc() {
        //I have a function in here
    }
}

I want to call the readFunc() in the service B. Could I do it in Android? Thank all. This is my service B

public class serviceB extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("A");
        intentFilter.addAction("B");
        registerReceiver(broadcastReceiver, intentFilter);
        return START_STICKY;
    }

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case "A":
                    Log.d(TAG,"A");
                    //Call the function here
                    break;
                case "B":
                    Log.d(TAG,"B");
                    break;
            }
        }
    };

}
user3051460
  • 1,455
  • 22
  • 58

2 Answers2

0

Well, you COULD do it, just instancing a new ServiceA and calling the function, but you should not do it like that. Services are not meant to be instantiated just to call a function which is not even part of the Service functionality. You have different options:

  • You could make readFunc() static if it does not modify variables of the class and you think it should belong to ServiceA and not to ServiceB. I don't think this is a goog approach in your case.
  • You could create a class ServiceAB which has readFunc(), and the define both ServiceA and B as "extends ServiceAB". Then both classes would inherit this function and you could just call readFunc() in both of them. I think this would be the correct approach in your case: both classes need some common functionality.
  • You could have readFunc() in a different class, and the instantiate it to use it in each of your services.

The way I would do it:

public class ServiceAB extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
        Log.d(TAG, "onCreate");
    }

    public void readFunc() {
        //I have a function in here
    }
}

Then:

public class serviceB extends ServiceAB {

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("A");
        intentFilter.addAction("B");
        registerReceiver(broadcastReceiver, intentFilter);
        return START_STICKY;
    }

    BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            switch (intent.getAction()) {
                case "A":
                    Log.d(TAG,"A");
                    readFunc(); //Just call the function
                    break;
                case "B":
                    Log.d(TAG,"B");
                    break;
            }
        }
    };

}

And ServiceA:

public class ServiceA extends ServiceAB {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        return START_NOT_STICKY;
    }

    private final IBinder mBinder = new LocalBinder();

}
ig343
  • 277
  • 1
  • 3
  • 17
0

Quoting @Kingfisher Phuoc here and @Mr Snowflake here

there are three obvious ways to communicate with services and EventBus:

  • Using Intents
  • Using AIDL
  • Using the service object itself (as singleton)
  • EventBus

    In your case, I'd go with option 3. Make a static reference to the service it self and populate it in onCreate():

    void onCreate(Intent i) { sInstance = this; }

Make a static function MyService getInstance(), which returns the static sInstance.

Then in Activity.onCreate() you start the service, asynchronously wait until the service is actually started (you could have your service notify your app it's ready by sending an Intent to the activity.) and get its instance.

When you have the instance, register your service listener object to you service and you are set.

NOTE: when editing Views inside the Activity you should modify them in the UI thread, the service will probably run its own Thread, so you need to call Activity.runOnUiThread().

The last thing you need to do is to remove the reference to you listener object in Activity.onPause(), otherwise an instance of your activity context will leak, not good.

NOTE: This method is only useful when your application/Activity/task is the only process that will access your service. If this is not the case you have to use option 1. or 2.

Community
  • 1
  • 1
HenriqueMS
  • 3,864
  • 2
  • 30
  • 39
  • @user3051460 have you been able to solve your problem? I believe this answer should be marked as correct , let me know if this helped =) – HenriqueMS Oct 17 '16 at 18:29