将服务绑定到 Android 中的活动
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1916253/
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
Bind service to activity in Android
提问by aspartame
I'm trying to write a simple media player that plays streaming audio using RTSP. I have a GUI-activity and a service that performs the playback. My question is how to best communicate between the activity and the service (e.g. updating the GUI based on the player state).
我正在尝试编写一个使用 RTSP 播放流音频的简单媒体播放器。我有一个 GUI 活动和一个执行播放的服务。我的问题是如何最好地在活动和服务之间进行通信(例如,根据玩家状态更新 GUI)。
I know that I can bind the service to the activity using onBind(), but if I understand correctly this will stop the service if the activity is killed. I want to continue the playback even if the user exits the activity. Is there any standard or preferred way of dealing with this problem?
我知道我可以使用 onBind() 将服务绑定到活动,但如果我理解正确,如果活动被终止,这将停止服务。即使用户退出活动,我也想继续播放。是否有任何标准或首选方法来处理此问题?
回答by Schildmeijer
"If you start an android Service with startService(..)
that Service will remain running until you explicitly invoke stopService(..)
.
There are two reasons that a service can be run by the system. If someone calls Context.startService()
then the system will retrieve the service (creating it and calling its onCreate()
method if needed) and then call its onStartCommand(Intent, int, int)
method with the arguments supplied by the client. The service will at this point continue running until Context.stopService()
or stopSelf()
is called. Note that multiple calls to Context.startService()
do not nest (though they do result in multiple corresponding calls to onStartCommand()
), so no matter how many times it is started a service will be stopped once Context.stopService()
or stopSelf()
is called; however, services can use their stopSelf(int)
method to ensure the service is not stopped until started intents have been processed.
“如果您使用startService(..)
该服务启动一个 android 服务,则该服务将保持运行状态,直到您显式调用stopService(..)
。服务可以由系统运行的原因有两个。如果有人调用,Context.startService()
则系统将检索该服务(创建它并调用它的onCreate()
方法,如果需要),然后onStartCommand(Intent, int, int)
使用客户端提供的参数调用其方法。此时服务将继续运行,直到Context.stopService()
或stopSelf()
被调用。请注意,多次调用Context.startService()
do not nest(尽管它们确实会导致对 的多次相应调用onStartCommand()
),因此没有无论启动多少次,服务都会被停止Context.stopService()
或被stopSelf()
调用;但是,服务可以使用它们的stopSelf(int)
方法来确保服务在启动的意图被处理之前不会停止。
Clients can also use Context.bindService()
to obtain a persistent connection to a service. This likewise creates the service if it is not already running (calling onCreate()
while doing so), but does not call onStartCommand()
. The client will receive the IBinder
object that the service returns from its onBind(Intent)
method, allowing the client to then make calls back to the service. The service will remain running as long as the connection is established (whether or not the client retains a reference on the Service's IBinder
). Usually the IBinder
returned is for a complex interface that has been written in AIDL.
客户端还可以Context.bindService()
用来获取到服务的持久连接。如果服务尚未运行(onCreate()
在这样做时调用),这同样会创建服务,但不会调用onStartCommand()
. 客户端将接收IBinder
服务从其onBind(Intent)
方法返回的对象,然后允许客户端调用回服务。只要建立连接,服务就会一直运行(无论客户端是否保留对服务的 的引用IBinder
)。通常IBinder
返回的是一个用 AIDL 编写的复杂接口。
A service can be both started and have connections bound to it. In such a case, the system will keep the service running as long as either it is started or there are one or more connections to it with the Context.BIND_AUTO_CREATE
flag. Once neither of these situations hold, the Service's onDestroy()
method is called and the service is effectively terminated. All cleanup (stopping threads, unregistering receivers) should be complete upon returning from onDestroy()
."
一个服务既可以启动也可以绑定连接。在这种情况下,只要服务已启动或有一个或多个带有Context.BIND_AUTO_CREATE
标志的连接,系统就会保持服务运行。一旦这两种情况都不成立,将onDestroy()
调用Service 的方法并有效地终止该服务。从 返回后,所有清理(停止线程、取消注册接收器)都应完成onDestroy()
。”
回答by Hardik Gajera
First of all, 2 thing that we need to understand
首先,我们需要了解两件事
Client
客户
it make request to specific server
bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);`
它向特定服务器发出请求
bindService(new Intent("com.android.vending.billing.InAppBillingService.BIND"), mServiceConn, Context.BIND_AUTO_CREATE);`
here mServiceConn
is instance of ServiceConnection
class(inbuilt) it is actually interface that we need to implement with two (1st for network connected and 2nd network not connected) method to monitor network connection state.
这mServiceConn
是ServiceConnection
类(内置)的实例,它实际上是我们需要用两个(第一个用于网络连接和第二个网络未连接)方法来监控网络连接状态的接口。
Server
服务器
- It handle the request of client and make replica of it's own which is private to client only who send request and this replica of server runs on different thread.
- 它处理客户端的请求并制作它自己的副本,该副本仅对发送请求的客户端是私有的,并且服务器的此副本运行在不同的线程上。
Now at client side, how to access all the method of server?
现在在客户端,如何访问服务器的所有方法?
server send response with IBind Object.so IBind object is our handler which access all the method of service by using (.) operator.
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; } }
服务器使用 IBind 对象发送响应。因此 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; } }
now how to call method which lies in service
现在如何调用服务中的方法
myservice.serviceMethod();
here myService
is object and serviceMethode
is method in service.
And by this way communication is established between client and server.
这里myService
是对象,serviceMethode
是服务中的方法。并通过这种方式在客户端和服务器之间建立通信。
回答by M.Hefny
I tried to call
我试着打电话
startService(oIntent);
bindService(oIntent, mConnection, Context.BIND_AUTO_CREATE);
consequently and I could create a sticky service and bind to it. Detailed tutorial for Bound Service Example.
因此,我可以创建一个粘性服务并绑定到它。绑定服务示例的详细教程。
回答by vrutberg
There is a method called unbindServicethat will take a ServiceConnection which you will have created upon calling bindService. This will allow you to disconnect from the service while still leaving it running.
有一个名为unbindService的方法,它将采用您在调用 bindService 时创建的 ServiceConnection。这将允许您在保持服务运行的同时断开与服务的连接。
This may pose a problem when you connect to it again, since you probably don't know whether it's running or not when you start the activity again, so you'll have to consider that in your activity code.
当您再次连接到它时,这可能会带来问题,因为当您再次启动活动时,您可能不知道它是否正在运行,因此您必须在活动代码中考虑这一点。
Good luck!
祝你好运!
回答by German
This is a biased answer, but I wrote a library that may simplify the usage of Android Services, if they run locally in the same process as the app: https://github.com/germnix/acacia
这是一个有偏见的答案,但我写了一个可以简化 Android 服务使用的库,如果它们在本地运行与应用程序相同的进程:https: //github.com/germnix/acacia
Basically you define an interface annotated with @Service and its implementing class, and the library creates and binds the service, handles the connection and the background worker thread:
基本上你定义一个用@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>
You can get an instance of the associated android.app.Service to hide/show persistent notifications, use your own android.app.Service and manually handle threading if you wish.
您可以获取关联 android.app.Service 的实例来隐藏/显示持久通知,使用您自己的 android.app.Service 并根据需要手动处理线程。
回答by Mira Febriani
If the user backs out, the onDestroy()
method will be called. This method is to stop any service that is used in the application. So if you want to continue the service even if the user backs out of the application, just erase onDestroy()
. Hope this help.
如果用户退出,该onDestroy()
方法将被调用。此方法用于停止应用程序中使用的任何服务。因此,如果您想在用户退出应用程序的情况下继续该服务,只需擦除即可onDestroy()
。希望这有帮助。