我可以从Android中的其他服务调用服务功能吗?

时间:2016-10-14 13:25:34

标签: android android-service android-service-binding

我在服务中有一个功能如下:

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
    }
}

我想拨打readFunc()中的service B。我可以在Android中做到吗?谢谢大家。这是我的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;
            }
        }
    };

}

2 个答案:

答案 0 :(得分:0)

好吧,你可以这样做,只是实例化一个新的ServiceA并调用该函数,但你不应该这样做。服务并不意味着只是为了调用甚至不属于服务功能的功能而实例化。您有不同的选择:

  • 如果不修改类的变量并且您认为它应该属于ServiceA而不属于ServiceB,则可以使readFunc()为静态。在你的情况下,我不认为这是一种goog方法。
  • 您可以创建一个具有readFunc()的ServiceAB类,并将ServiceA和B定义为"扩展ServiceAB"。然后这两个类都将继承这个函数,你可以在它们中调用readFunc()。我认为这将是您的正确方法:两个类都需要一些通用功能。
  • 您可以在其他类中使用readFunc(),并将其实例化以在每个服务中使用它。

我会这样做:

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

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

然后:

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;
            }
        }
    };

}

和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();

}

答案 1 :(得分:0)

引用@Kingfisher Phuoc here和@Mr Snowflake here

有三种明显的方式与服务和EventBus进行通信:

  • 使用意图
  • 使用AIDL
  • 使用服务对象本身(作为单身人士)
  • EventBus

    在你的情况下,我会选择选项3.对自己的服务进行静态引用并在onCreate()中填充它:

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

创建一个静态函数MyService getInstance(),它返回静态sInstance。

然后在Activity.onCreate()启动服务, 异步等待服务实际启动(您可以让服务通过向活动发送Intent来通知您的应用程序已准备好。)并获取其实例。

获得实例后,将服务侦听器对象注册到您的服务并进行设置。

注意:在Activity中编辑Views时你应该在UI线程中修改它们,服务可能会运行自己的Thread,所以你需要调用Activity.runOnUiThread()。

您需要做的最后一件事是删除Activity.onPause()中对您的侦听器对象的引用,否则您的活动上下文的实例将泄漏,而不是好。

注意:此方法仅在您的应用程序/活动/任务是仅访问您服务的流程时才有用。如果不是这种情况,您必须使用选项1或2