【问题标题】:Could I call a function of service from another service in Android?我可以从 Android 中的另一个服务调用服务功能吗?
【发布时间】:2016-10-14 21:47:08
【问题描述】:

我在一个服务中有一个函数如下:

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

我想在service B 中调用readFunc()。我可以在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;
            }
        }
    };

}

【问题讨论】:

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


    【解决方案1】:

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

    • 如果 readFunc() 不修改类的变量并且您认为它应该属于 ServiceA 而不是 ServiceB,则可以将其设为静态。在您的情况下,我认为这不是一种 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;
                }
            }
        };
    
    }
    

    和服务A:

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

    【讨论】:

      【解决方案2】:

      引用@Kingfisher Phuoc here 和@Mr Snowflake here

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

      • 使用意图
      • 使用 AIDL
      • 使用服务对象本身(作为单例)
      • 事件总线

        在您的情况下,我会选择选项 3。对其自身的服务进行静态引用并将其填充到 onCreate() 中:

        void onCreate(Intent i) { sInstance = 这个; }

      制作一个静态函数MyService getInstance(),返回静态sInstance。

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

      当您拥有实例后,将您的服务侦听器对象注册到您的服务并设置好。

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

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

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

      【讨论】:

      • @user3051460 你能解决你的问题吗?我相信这个答案应该被标记为正确,如果这有帮助,请告诉我=)
      猜你喜欢
      • 1970-01-01
      • 2011-06-07
      • 1970-01-01
      • 2018-03-21
      • 2018-02-20
      • 2015-01-10
      • 2017-04-01
      • 2011-08-06
      • 1970-01-01
      相关资源
      最近更新 更多