Android Service 服务(三)—— bindService与remoteService

article/2025/10/1 9:29:45

一、bindService简介

bindService是绑定Service服务,执行service服务中的逻辑流程。

service通过Context.startService()方法开始,通过Context.stopService()方法停止;也可以通过Service.stopSelf()方法或者Service.stopSelfResult()方法来停止自己。只要调用一次stopService()方法便可以停止服务,无论之前它被调用了多少次的启动服务方法。

 

客户端建立一个与Service的连接,并使用此连接与Service进行通话,通过Context.bindService()方法来绑定服务,Context.unbindService()方法来关闭服务。多个客户端可以绑定同一个服务,如果Service还未被启动,bindService()方法可以启动服务。

 

上面startService()和bindService()两种模式是完全独立的。你可以绑定一个已经通过startService()方法启动的服务。例如:一个后台播放音乐服务可以通过startService(intend)对象来播放音乐。可能用户在播放过程中要执行一些操作比如获取歌曲的一些信息,此时activity可以通过调用bindServices()方法与Service建立连接。这种情况下,stopServices()方法实际上不会停止服务,直到最后一次绑定关闭。


二、bindService启动流程

context.bindService()  ——> onCreate()  ——onBind()  ——> Service running  ——onUnbind()  ——onDestroy()  ——Service stop
 

onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。 

所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。

在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。详见:Android Service 服务(一)—— Service


三、bindService生命周期

像一个activity那样,一个service有些可以用来改变状态的生命周期方法,但是比activity的方法少,service生命周期方法只有三个public

   void onCreate()

   void onStart(Intent intent)

   void onDestroy()

通过实现这三个生命周期方法,你可以监听service的两个嵌套循环的生命周期:

1、整个生命周期

 service的整个生命周期是在onCreate()和onDestroy()方法之间。和activity一样,在onCreate()方法里初始化,在onDestroy()方法里释放资源。例如,一个背景音乐播放服务可以在onCreate()方法里播放,在onDestroy()方法里停止。

 

2、活动的生命周期

 service的活动生命周期是在onStart()之后,这个方法会处理通过startServices()方法传递来的Intent对象。音乐service可以通过开打intent对象来找到要播放的音乐,然后开始后台播放。注: service停止时没有相应的回调方法,即没有onStop()方法,只有onDestroy()销毁方法。

 

onCreate()方法和onDestroy()方法是针对所有的services,无论它们是否启动,通过Context.startService()和Context.bindService()方法都可以访问执行。然而,只有通过startService()方法启动service服务时才会调用onStart()方法

 

如果一个service允许别人绑定,那么需要实现以下额外的方法:

       IBinder onBind(Intent intent)

       boolean onUnbind(Intent intent)

       void onRebind(Intent intent)

onBind()回调方法会继续传递通过bindService()传递来的intent对象

onUnbind()会处理传递给unbindService()的intent对象。如果service允许绑定,onBind()会返回客户端与服务互相联系的通信句柄(实例)。

如果建立了一个新的客户端与服务的连接,onUnbind()方法可以请求调用onRebind()方法。


记住: 任何服务无论它怎样建立,默认客户端都可以连接,所以任何service都能够接收onBind()和onUnbind()方法



四、bindService示例

Activity

public class PlayBindMusic extends Activity implements OnClickListener {private Button playBtn;private Button stopBtn;private Button pauseBtn;private Button exitBtn;private BindMusicService musicService;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.bind_music_service);playBtn = (Button) findViewById(R.id.play);stopBtn = (Button) findViewById(R.id.stop);pauseBtn = (Button) findViewById(R.id.pause);exitBtn = (Button) findViewById(R.id.exit);playBtn.setOnClickListener(this);stopBtn.setOnClickListener(this);pauseBtn.setOnClickListener(this);exitBtn.setOnClickListener(this);connection();}private void connection() {Intent intent = new Intent("com.homer.bind.bindService");bindService(intent, sc, Context.BIND_AUTO_CREATE);			// bindService}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.play:musicService.play();break;case R.id.stop:if (musicService != null) {musicService.stop();}break;case R.id.pause:if (musicService != null) {musicService.pause();}break;case R.id.exit:this.finish();break;}}private ServiceConnection sc = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {		//connect ServicemusicService = ((BindMusicService.MyBinder) (service)).getService();if (musicService != null) {musicService.play();		// play music}}@Overridepublic void onServiceDisconnected(ComponentName name) {					//disconnect ServicemusicService = null;}};@Overridepublic void onDestroy(){super.onDestroy();if(sc != null){unbindService(sc);}}
}

Service

public class BindMusicService extends Service {private MediaPlayer mediaPlayer;private final IBinder binder = new MyBinder();public class MyBinder extends Binder {BindMusicService getService() {return BindMusicService.this;}}@Overridepublic IBinder onBind(Intent intent) {return binder;}@Overridepublic void onCreate() {super.onCreate();Toast.makeText(this, "show media player", Toast.LENGTH_SHORT).show();}@Overridepublic void onDestroy() {super.onDestroy();Toast.makeText(this, "stop media player", Toast.LENGTH_SHORT);if(mediaPlayer != null){mediaPlayer.stop();mediaPlayer.release();}}public void play() {if (mediaPlayer == null) {mediaPlayer = MediaPlayer.create(this, R.raw.tmp);mediaPlayer.setLooping(false);}if (!mediaPlayer.isPlaying()) {mediaPlayer.start();}}public void pause() {if (mediaPlayer != null && mediaPlayer.isPlaying()) {mediaPlayer.pause();}}public void stop() {if (mediaPlayer != null) {mediaPlayer.stop();try {mediaPlayer.prepare();		// 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数} catch (IOException ex) {ex.printStackTrace();}}}
}

AndroidManifest.xml

        <serviceandroid:name=".bind.BindMusicService"android:enabled="true" ><intent-filter><action android:name="com.homer.bind.bindService" /></intent-filter></service>


五、代码解析

1、 Activity中,Intent intent = new Intent("com.homer.bind.bindService"); 构建一个service的action,然后bindService(intent, sc, Context.BIND_AUTO_CREATE); 绑定服务

2、 Activity中,通过private ServiceConnection sc = new ServiceConnection() 建立一个Service连接,onServiceConnected()获取Service实例,onServiceDisconnected()释放连接

3、 Service中,重载onBind(Intent intent)方法,返回Service实例(即BindMusicService)给Activity,然后执行onCreate()函数(注:bindService不执行onStart()函数)

4、 Activity中,通过返回的Service实例musicService,执行音乐播放的操作(play、pause、stop等)



六、Remote Service拓展

通常每个应用程序都在它自己的进程内运行,但有时需要在进程之间传递对象(IPC通信),你可以通过应用程序UI的方式写个运行在一个不同的进程中的service。在android平台中,一个进程通常不能访问其它进程中的内存区域。所以,他们需要把对象拆分成操作系统能理解的简单形式,以便伪装成对象跨越边界访问。编写这种伪装代码相当的枯燥乏味,好在android为我们提供了AIDL工具可以来做这件事。
 
AIDL(android接口描述语言)是一个IDL语言,它可以生成一段代码,可以使在一个android设备上运行的两个进程使用内部通信进程进行交互。如果你需要在一个进程中(例如在一个Activity中)访问另一个进程中(例如一个Service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。
 
要使用AIDL,Service需要以aidl文件的方式提供服务接口,AIDL工具将生成一个相应的java接口,并且在生成的服务接口中包含一个功能调用的stub服务桩类。Service的实现类需要去继承这个stub服务桩类。Service的onBind方法会返回实现类的对象,之后你就可以使用它了,参见下例:

IMusicControlService.aidl

package com.homer.remote;interface IMusicControlService{void play(); void stop(); void pause();
}

使用eclipse的Android插件,会根据这个aidl文件生成一个Java接口类,生成的接口类中会有一个内部类Stub类,Service来继承该Stub类:
Service
public class RemoteMusicService extends Service {private MediaPlayer mediaPlayer;@Overridepublic IBinder onBind(Intent intent) {return binder;}private final IMusicControlService.Stub binder = new IMusicControlService.Stub() {@Overridepublic void play() throws RemoteException {if (mediaPlayer == null) {mediaPlayer = MediaPlayer.create(RemoteMusicService.this, R.raw.tmp);mediaPlayer.setLooping(false);}if (!mediaPlayer.isPlaying()) {mediaPlayer.start();}}@Overridepublic void pause() throws RemoteException {if (mediaPlayer != null && mediaPlayer.isPlaying()) {mediaPlayer.pause();}			}@Overridepublic void stop() throws RemoteException {if (mediaPlayer != null) {mediaPlayer.stop();try {mediaPlayer.prepare();		// 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数} catch (IOException ex) {ex.printStackTrace();}}}};@Overridepublic void onDestroy() {super.onDestroy();if(mediaPlayer != null){mediaPlayer.stop();mediaPlayer.release();}}
}

客户端(Activity)应用连接到这个Service时,onServiceConnected方法将被调用,客户端就可以获得IBinder对象。参看下面的客户端onServiceConnected方法:

Activity

public class PlayRemoteMusic extends Activity implements OnClickListener {private Button playBtn;private Button stopBtn;private Button pauseBtn;private Button exitBtn;private IMusicControlService musicService;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.remote_music_service);playBtn = (Button) findViewById(R.id.play);stopBtn = (Button) findViewById(R.id.stop);pauseBtn = (Button) findViewById(R.id.pause);exitBtn = (Button) findViewById(R.id.exit);playBtn.setOnClickListener(this);stopBtn.setOnClickListener(this);pauseBtn.setOnClickListener(this);exitBtn.setOnClickListener(this);connection();}private void connection() {Intent intent = new Intent("com.homer.remote.remoteMusicReceiver");bindService(intent, sc, Context.BIND_AUTO_CREATE);				// bindService}@Overridepublic void onClick(View v) {try {switch (v.getId()) {case R.id.play:musicService.play();break;case R.id.stop:if (musicService != null) {musicService.stop();}break;case R.id.pause:if (musicService != null) {musicService.pause();}break;case R.id.exit:this.finish();break;}} catch (RemoteException e) {e.printStackTrace();}}private ServiceConnection sc = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {		//connect ServicemusicService = IMusicControlService.Stub.asInterface(service);}@Overridepublic void onServiceDisconnected(ComponentName name) {					//disconnect ServicemusicService = null;}};@Overridepublic void onDestroy(){super.onDestroy();if(sc != null){unbindService(sc);				// unBindService}}
}

Remote Service流程总结:

1、 Activity(客户端)中,Intent intent = new Intent("com.homer.remote.remoteMusicReceiver");构建intent,然后bindService(intent, sc, Context.BIND_AUTO_CREATE);绑定服务

2、 Activity(客户端)中,通过ServiceConnection()重载onServiceConnected()建立连接,获取Service.Stub实例;onServiceDisconnected()释放连接(与bindService类似)

3、 Service中,通过重载onBind(Intent intent) 返回Service.Stub实例,但Service.Stub类是由aidl文件生成的接口类中的一个内部类Stub类,Service来继承该Stub类

4、 Activity中,通过操作Service实例(musicService),执行音乐播放操作(play、pause、stop等)


源码下载



参考推荐:

Service (android developer)

Android Service 服务(一)—— Service

Android Service 服务(二)—— BroadcastReceiver

android中service和aidl详细整理

Android Service AIDL

android笔记--Service与AIDL



http://chatgpt.dhexx.cn/article/8eq7Lo1Y.shtml

相关文章

SO_BINDTODEVICE 使用

就绑定到了接口"lmi40"上,所有数据报的收发都只经过这个网卡. 对于SOL_BINDTODEVICE的总结如下: &#xff08;1&#xff09; 对于TCP套接口、UDP套接口、RAW套接口&#xff0c;可以通过SO_BINDTODEVICE套接口选项将套接口绑定到指定的网络接口上。绑定之后&…

startService与bindService的区别

Android执行Service有两种方法&#xff0c;一种是startService&#xff0c;一种是bindService。下面让我们一起来聊一聊这两种执行Service方法的区别。 1、生命周期上的区别 执行startService时&#xff0c;Service会经历onCreate->onStartCommand。当执行stopService时&…

startService和bindService的区别

首先看下其生命周期的区别&#xff1a; 生命周期&#xff1a; onCreate → startCommand → onDestroy onCreate → onBind→onUnBind→ onDestroy 静态绑定对应着startService&#xff1b;动态绑定对应着bindService&#xff0c;静态有自己独立的生命周期&#xff0c;动态会…

bindService的使用

bindService与starService之间的区别&#xff1a; 在程序通过startService&#xff08;&#xff09;方法启动的服务&#xff0c;会长期在后台运行&#xff0c;并且启动服务的组件与服务之间没有关系&#xff0c;即使启动服务的组件被销毁&#xff0c;服务还是会运行。 但是当一…

Service学习以及BindService的使用

Service 什么是Service Service是一个可以在后台执行长时间操作而不使用用户界面的应用组件。 如何使用Service 我们首先需要实现一个Service的子类。主要实现Service的onCreat&#xff08;&#xff09;&#xff0c;onStartCommand&#xff08;&#xff09;&#xff0c;onB…

Android中bindService的使用及Service生命周期

Android中有两种主要方式使用Service&#xff0c;通过调用Context的startService方法或调用Context的bindService方法&#xff0c;本文只探讨纯bindService的使用&#xff0c;不涉及任何startService方法调用的情况。如果想了解startService相关的使用&#xff0c;请参见《Andr…

粒子群算法笔记

实质&#xff1a;在定义域随机放置多个变量&#xff0c;不断跳跃&#xff0c;同步寻找最优解。寻找方向受单个粒子与全部粒子的最优位置共同影响。单个粒子按照公式不断迭代寻找当新位置。多个变量聚集在某一点时&#xff0c;该点即是最优解。 控制其搜索速度&#xff08;步长…

粒子群算法及C++实现

参考博客 https://www.cnblogs.com/alan666/p/8311804.html https://blog.csdn.net/weixin_39059031/article/details/103723843 https://blog.csdn.net/weixin_40679412/article/details/80571854 https://blog.csdn.net/daaikuaichuan/article/details/81382794 https://blo…

粒子群算法详解

一.产生背景 ❃粒子群算法(particleswarm optimization&#xff0c;PSO)由Kennedy和Eberhart在1995年提出&#xff0c;该算法对于Hepper的模拟鸟群(鱼群)的模型进行修正&#xff0c;以使粒子能够飞向解空间&#xff0c;并在最好解处降落&#xff0c;从而得到了粒子群优化算法。…

高铁列车粒子群算法及改进粒子群算法多目标单目标运行优化设计

问题介绍 根据表1、2、3 所列数据&#xff0c;以能耗、运行时间、舒适性为目标分别设计列车运行速度—距离曲线&#xff1b;完成单目标以及多目标优化下的列车运行对比&#xff1b;选择其中一种方案&#xff0c;设计列车速度跟踪控制算法并进行性能分析。 1 列车参数设置表优化…

智能优化算法之粒子群算法

1、粒子群优化算法概述 粒子群优化算法(PSO&#xff1a;Particle swarm optimization) 是一种进化计算技术&#xff08;evolutionary computation&#xff09;。源于对鸟群捕食的行为研究。粒子群优化算法的基本思想&#xff1a;是通过群体中个体之间的协作和信息共享来寻找最优…

基于群智能的三维路径规划算法 2 —— 粒子群算法

目录 1 PSO算法的基本理论2 PSO算法程序设计流程3 MATLAB编程实现4 算法举例5 函数1 unifrnd函数 1 PSO算法的基本理论 将三个散点看做一个粒子 惯性分量就是 v i − 1 d v^d_{i-1} vi−1d​ 粒子群&#xff08;PSO&#xff09;算法是依托群鸟觅食的模型寻找最优解。群体特征…

粒子群算法(2)

上一期&#xff1a;粒子群算法&#xff08;1&#xff09; 线性递减惯性权重 惯性权重w体现的是粒子继承先前的速度的能力&#xff0c;Shi,Y最先将惯性权重w引入到粒子群算法中&#xff0c;并分析指出一个较大的惯性权值有利于全局搜索&#xff0c;而一个较小的权值则更利于局部…

粒子群算法简介

粒子群算法简介 前言 本文内容借鉴于 刘衍民的博士论文:“粒子群算法的研究及应用”. 现有的大多数群智能算法,如:乌鸦算法、鸽子算法、蚁群算法、萤火虫算法和灰狼优化算法等&#xff0c;都可以归类为粒子群算法.(个人觉得,这些算法就是整个稀奇古怪的名字,颇有舞文弄墨,强…

粒子群算法(1)

粒子群算法 1.入门 粒子群算法&#xff0c;其全称为粒子群优化算法(Particle Swarm Optimization,PsO)。它是通过模拟鸟群觅食行为而发展起来的一种基于群体协作的搜索算法。 2.什么是启发式算法&#xff1f; 启发式算法百度百科上的定义:一个基于直观或经验构造的算法,在可…

粒子群优化算法

背景 1995 年&#xff0c;Kennedy 和 Eberhart 两位博士共同 提出了粒子群优化算法 (Particle swarm optimization&#xff0c; PSO) PSO 算法中&#xff0c;将鸟群的个体位置或食物当作优化问题的解&#xff0c;利用群体中个体与最优个体以及个体之间的信息交互&#xff0c;引…

粒子群算法

粒子群算法简介 粒子群算法&#xff0c;其全称为粒子群优化算法(Particle Swarm Optimization,PSO) 。它是通过模拟鸟群觅食行为而发展起来的一种基于群体协作的搜索算法。粒子群算法属于启发式算法也叫智能优化算法&#xff0c;其基本思想在于通过群体中个体之间的协作和信息…

粒子群(PSO)算法的理解与应用

最近在学习粒子群算法&#xff0c;看了很多资料都有点摸不清头脑&#xff0c;直到看了一篇博客中超级简洁的粒子群C实现代码&#xff0c;才明白粒子群算法的原理&#xff0c;真心感谢博主&#xff0c;在此贴出博主的博客地址&#xff1a; http://blog.sina.com.cn/s/blog_4ed02…

6套粒子群算法(内含matlab代码)

粒子群算法(1)----粒子群算法简介 一、粒子群算法的历史 粒子群算法源于复杂适应系统&#xff08;Complex Adaptive System,CAS&#xff09;。CAS理论于1994年正式提出&#xff0c;CAS中的成员称为主体。比如研究鸟群系统&#xff0c;每个鸟在这个系统中就称为主体。主体有适…

粒子群算法(PSO)详解

1 粒子群PSO算法简介 1.1 维基百科的解释 粒子群算法&#xff08;Particle Swarm Optimization&#xff0c;简称PSO&#xff09;&#xff0c;或称粒子群优化&#xff0c;是属于人工智能算法&#xff0c;公元1995年由肯尼迪&#xff08;Kennedy&#xff09;与埃伯哈特&#xf…