将服务绑定到Android中的活动


90

我正在尝试编写一个简单的媒体播放器,该播放器使用RTSP播放流音频。我具有GUI活动和执行回放的服务。我的问题是如何在活动和服务之间进行最佳沟通(例如,根据玩家状态更新GUI)。

我知道我可以使用onBind()将服务绑定到活动,但是如果我理解正确的话,如果活动被杀死,这将停止服务。即使用户退出活动,我也想继续播放。是否有任何标准或首选的方式来处理此问题?

Answers:


154

“如果您启动一个android服务,并且startService(..)该服务将一直运行直到您显式调用stopService(..)。系统可以运行该服务有两个原因。如果有人调用,Context.startService()则系统将检索该服务(创建该服务并在调用该onCreate()方法时调用该方法然后onStartCommand(Intent, int, int)使用客户端提供的参数调用其方法。该服务将继续运行直到Context.stopService()或被stopSelf()调用。请注意,多次调用Context.startService()不会嵌套(尽管它们确实导致对的多次调用onStartCommand()),所以没有无论启动多少次,服务都会停止一次Context.stopService()或被stopSelf()调用;但是,服务可以使用它们stopSelf(int) 确保在处理启动的意图之前不停止服务的方法。

客户端还可以Context.bindService()用于获取与服务的持久连接。如果该服务尚未运行(onCreate()在运行时进行调用),但尚未运行,则同样会创建该服务onStartCommand()。客户端IBinder将从其onBind(Intent)方法接收服务返回的对象,从而允许客户端随后调用该服务。只要建立了连接,该服务就会一直运行(无论客户端是否保留对Service的引用IBinder)。通常,IBinder返回的结果是使用AIDL编写的复杂接口。

服务既可以启动,也可以绑定连接。在这种情况下,只要服务启动或带有该Context.BIND_AUTO_CREATE标志的一个或多个连接,系统就会保持该服务运行。一旦这两种情况均不成立,则将onDestroy()调用Service的方法,并有效终止该服务。从返回时,所有清理(停止线程,注销接收器)都应完成onDestroy()。”


1
有点困惑:是的,如果活动被破坏了,服务也将被破坏吗?还是仅当我实现自己的AIDL时才会销毁该服务?我问是因为当我使用startService(特别是IntentService上的服务)时,服务将在其工作完成时停止,而不是在活动终止时停止。那么,如果活动死亡,那么绑定的服务(也排他地)也死亡,这是真的吗?
Katedral Pillon

1
如果您通过调用startService使用简单服务器,则只有在调用stopSelf()或stopService()时服务才会停止。接下来,如果您使用bindService,则如果所有连接/绑定组件都销毁,则yes服务将消失。
阿西夫·穆斯塔克

1
@UnKnown如果使用startService()启动服务,则无论您绑定还是取消绑定,它都将继续运行,并且只能通过调用stopService()或stopSelf()销毁。因此,即使绑定到该服务的活动被破坏,该服务也不会被破坏。
CopsOnRoad


25

首先,我们需要了解两件事

客户

  • 向特定服务器发出请求

    bindService(new 
        Intent("com.android.vending.billing.InAppBillingService.BIND"),
            mServiceConn, Context.BIND_AUTO_CREATE);`

mServiceConnServiceConnection类(内置)的实例,它实际上是我们需要使用两种方法(用于连接网络的第一个和未连接网络的第二个)实现的接口,以监视网络连接状态。

服务器

  • 它处理客户端的请求并制作自己的副本,该副本仅对发送请求的客户端私有,并且此服务器副本在不同的线程上运行。

现在在客户端,如何访问服务器的所有方法?

  • 服务器使用IBind Object.so发送响应。因此IBind对象是我们的处理程序,该处理程序使用(。)运算符访问所有服务方法。

    MyService myService;
    public ServiceConnection myConnection = new ServiceConnection() {
        public void onServiceConnected(ComponentName className, IBinder binder) {
            Log.d("ServiceConnection","connected");
            myService = binder;
        }
        //binder comes from server to communicate with method's of 
    
        public void onServiceDisconnected(ComponentName className) {
            Log.d("ServiceConnection","disconnected");
            myService = null;
        }
    }

现在如何调用服务中的方法

myservice.serviceMethod();

myService是对象,serviceMethode是服务中的方法。并以此方式在客户端和服务器之间建立通信。


10

我试图打电话

startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);

因此,我可以创建一个粘性服务并将其绑定。绑定服务示例的详细教程。


5

有一个名为unbindService的方法,它将采用您在调用bindService时创建的ServiceConnection。这样,您就可以与服务断开连接,同时仍保持运行状态。

当您再次连接它时,这可能会引起问题,因为当您再次启动该活动时,您可能不知道它是否正在运行,因此您必须在活动代码中加以考虑。

祝好运!


-1

这是一个有偏见的答案,但是我编写了一个库,可以简化Android服务的使用,如果它们在与应用程序相同的过程中本地运行:https : //github.com/germnix/acacia

基本上,您定义一个用@Service及其实现类注释的接口,该库创建并绑定服务,处理连接和后台工作线程:

@Service(ServiceImpl.class)
public interface MyService {
    void doProcessing(Foo aComplexParam);
}

public class ServiceImpl implements MyService {
    // your implementation
}

MyService service = Acacia.createService(context, MyService.class);
service.doProcessing(foo);

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">
    ...
    <service android:name="com.gmr.acacia.AcaciaService"/>
    ...
</application>

您可以获取关联的android.app.Service的实例来隐藏/显示持久性通知,使用自己的android.app.Service并根据需要手动处理线程。


-5

如果用户退出,onDestroy()则将调用该方法。此方法是停止应用程序中使用的任何服务。因此,即使用户退出了应用程序,如果您想继续该服务,只需擦除即可onDestroy()。希望有帮助。


如果IDE自动创建一个函数,则必须重写该函数并删除对超类的onDestroy()的默认调用。但是为什么要这么做呢?
Riptyde4 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.