Android 将服务绑定到活动或片段?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24309379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 08:00:44  来源:igfitidea点击:

Bind service to activity or fragment?

androidandroid-fragmentsandroid-service

提问by Anjani

I am working on a music player app. I have a main activity which has multiple fragments, each displaying songs on the device album wise, artist wise etc..
I have a music service which handles all the playback and other stuff.
What I'm confused about is the binding of this service with various fragments I have.
Right now I'm binding the main activity and each fragment individually with the service and its working pretty much fine. But I was wondering if this is really the best practice? Is there any way to just bind the main activity with the service and then some how use it in its child fragments?
I maybe missing some very basic concept of activity or fragments or services. So someone please guide me in this regard.
I guess it's more of a conceptual question so any code isn't needed. But still if it's required then please let me know.

我正在开发音乐播放器应用程序。我有一个包含多个片段的主要活动,每个片段都在设备专辑、艺术家等方面显示歌曲。
我有一个音乐服务来处理所有播放和其他内容。
我感到困惑的是该服务与我拥有的各种片段的绑定。
现在我将主要活动和每个片段单独与服务绑定,并且它的工作非常好。但我想知道这是否真的是最佳实践?有什么方法可以将主要活动与服务绑定,然后在其子片段中使用它吗?
我可能遗漏了一些非常基本的活动或片段或服务的概念。所以请有人在这方面指导我。
我想这更像是一个概念性问题,因此不需要任何代码。但如果需要,请告诉我。

EDIT :
My question is: What would be a better way to bind a service with an activity with multiple child fragments(each of which would be using the service)?

编辑:
我的问题是:将服务与具有多个子片段(每个片段都将使用该服务)的活动绑定在一起的更好方法是什么?

采纳答案by Rarw

Bind the Serviceto your activity and not the Fragment. The description of your application, one activity with multiple Fragmentthat are swapped in and out, makes this the most (and really only) practical approach.

将 绑定Service到您的活动而不是Fragment. 对您的应用程序的描述,即一个具有多个Fragment交换进出的活动,使这成为最(也是唯一)实用的方法。

When you bind a Serviceto an Activityyou are tying its lifecycle to that of the Activity. SeeBound Services. Each time you add or remove a Fragmentin your activity that Fragmentis created and destroyed. You do not want to try to link a service to this process because then you would have to create and destroy the service each time a new fragment is created or destroyed.

当您将 a 绑定Service到 an 时,Activity您将其生命周期与Activity. 请参阅绑定服务。每次FragmentFragment创建和销毁的活动中添加或删除一个。您不想尝试将服务链接到此流程,因为这样每次创建或销毁新片段时都必须创建和销毁服务。

Instead bind to the host Activity. You can then interact with your host activity from your fragments with an interface to access the bound service or by Intent.

而是绑定到主机Activity。然后,您可以通过接口与片段中的主机活动进行交互,以访问绑定服务或通过Intent.

回答by Ena

I think the cleaner architecture is to bind directly from the fragment. Regarding the problem outlined in Rarw's answer, you can bind to the service from your activity and from your fragments too. This way you are sure that the service will be there until the activity is not destroyed.

我认为更简洁的架构是直接从片段绑定。关于 Rarw 的回答中概述的问题,您也可以从您的活动和片段绑定到服务。通过这种方式,您可以确保服务会一直存在,直到活动没有被销毁。

I can see two main advantages in connecting from the fragment:

我可以看到从片段连接的两个主要优点:

  1. Service connection is async, so inside the fragment you are never really sure that the service you are getting from the activity is not null. This will lead you at least to some null pointer checks and to some mechanism to refresh the fragment both when it's created and when the service connects (so you are sure you will display the data no matter which of the two happens first).

  2. You do not depend on the particular activity your fragments lives in. To get the service from the activity I think you are doing a cast to the activity specific class. You could create an interface like BoundActivitywith a method like getBoundServiceto obtain the service from it, but I think it's an overhead considering the advantage of point 1. And what if you have multiple services.

  1. 服务连接是异步的,因此在片段中,您永远无法确定从活动中获得的服务不为空。这将至少引导您进行一些空指针检查,以及在片段创建和服务连接时刷新片段的某种机制(因此您确定无论两者中的哪一个先发生,您都会显示数据)。

  2. 您不依赖于片段所在的特定活动。为了从活动中获取服务,我认为您正在对活动特定类进行转换。您可以创建一个接口,例如BoundActivity使用类似的方法getBoundService从中获取服务,但考虑到第 1 点的优势,我认为这是一种开销。如果您有多个服务,该怎么办。

UPDATE

更新

Here is a very simple project showing this. https://github.com/ena1106/FragmentBoundServiceExample

这是一个非常简单的项目,展示了这一点。 https://github.com/ena1106/FragmentBoundServiceExample

回答by junique

The only method I have found to be reliable is to use a loader in Fragment:

我发现唯一可靠的方法是在 中使用加载器Fragment

  1. create a Loaderin the fragment
  2. use the contextof the Loader(set to activityin initLoaderat when the Fragment's onCreateis called)
  3. bind the service in onStartLoading, using a ServiceConnectionwhich calls forceLoad()as soon as the service is bound
  4. optionally register callbacks in onStartLoading/onStopLoading
  5. unbind the service in onStopLoading
  1. Loader在片段中创建一个
  2. 使用context中的Loader(设置为activityinitLoader在当碎片的onCreate叫法)
  3. 将服务绑定到 中onStartLoading,使用ServiceConnectionforceLoad()在服务绑定后立即调用
  4. 可选地在onStartLoading/ 中注册回调onStopLoading
  5. 解除绑定服务 onStopLoading

回答by Informatheus

IF you need to get some data from your service to your fragment at the beginning of the fragment lifecycle, the onServiceConnected on activity could not be called yet, mainly when you rotate your device, and you'll get a NPE. I think is a good idea let fragment make his own connections since the service is started with startService() and not with bindService().

如果您需要在片段生命周期开始时从您的服务获取一些数据到片段,则无法调用 onServiceConnected on 活动,主要是在您旋转设备时,您将获得一个 NPE。我认为让 fragment 建立自己的连接是个好主意,因为服务是用 startService() 而不是用 bindService() 启动的。

回答by fantianwen

I bind service in My Host Activity,and pass Ibinder's object by Bundle which is setted in arguments.

我在我的主机活动中绑定服务,并通过在参数中设置的 Bundle 传递 Ibinder 的对象。

and my code may like this:

我的代码可能是这样的:

private ServiceConnection mConnection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //put service in bundle
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};

回答by Alexander Kulyakhtin

You can access your activity from a fragment by getActivity()

您可以通过以下方式从片段访问您的活动 getActivity()

回答by ingyesid

you can tray using the event bus pattern with this library , eventbus publish/subscribe pattern.https://github.com/greenrobot/EventBuscheck the project site for more information.

你可以使用带有这个库的事件总线模式,事件总线发布/订阅模式。https://github.com/greenrobot/EventBus检查项目站点以获取更多信息。

you can send events from/to service to active or fragments

您可以从/向服务发送事件到活动或片段