简介 :

创建一个服务

 class TestService extends Service {@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent arg0) {return null;}} 

第一个方法onCreate只有在Service被创建的时刻被调用。如果Service已经在运行中,这个方法将不会被调用。我们不能直接调用它,它是由系统负责调用的。

OnStartCommand方法是最重要的方法,因为它在我们需要启动Service的时候被调用。在这个方法中,我们拥有在运行Service 时传递进来的Intent,这样就可以与Service交换一些信息。在这个方法中,我们实现自己的逻辑:如果不是耗时的操作可以直接在这个方法中执行, 否则可以创建一个线程。正如你看到的那样,这个方法需要返回一个整型值。这个整型代表系统应该怎么样处理这个Service:

  • START_STICKY:使用这个返回值,如果系统杀死我们的Service将会重新创建。但是,发送给Service的Intent不会再投递。这样Service是一直运行的。
  • START_NOT_STICKY:如果系统杀死了Service,不会重新创建,除非客户端显式地调用了onStart命令。
  • START_REDELIVER_INTENT:功能与START_STICKY类似。另外,在这种情况下Intent会重新传递给Service。

OnDestory是在Service将被销毁时系统调用的方法。

一旦有了自定义的Service类,就要在Manifest.xml中声明,这样我们就可以使用了。

service的生命周期

被启动的服务的生命周期:

如果一个Service被某个Activity 调用 Context.startService 方法启动,那么不管是否有Activity使用bindService绑定或unbindService解除绑定到该Service,该Service都在后台运行。如果一个Service被startService 方法多次启动,那么onCreate方法只会调用一次,onStart将会被调用多次(对应调用startService的次数),并且系统只会创建Service的一个实例(因此你应该知道只需要一次stopService调用)。该Service将会一直在后台运行,而不管对应程序的Activity是否在运行,直到被调用stopService,或自身的stopSelf方法。当然如果系统资源不足,android系统也可能结束服务

被绑定的服务的生命周期:

如果一个Service被某个Activity 调用 Context.bindService 方法绑定启动,不管调用 bindService 调用几次,onCreate方法都只会调用一次,同时onStart方法始终不会被调用。当连接建立之后,Service将会一直运行,除非调用Context.unbindService 断开连接或者之前调用 bindService 的 Context 不存在了(如Activity被finish的时候),系统将会自动停止Service,对应onDestroy将被调用。

被启动又被绑定的服务的生命周期:

如果一个Service又被启动又被绑定,则该Service将会一直在后台运行。并且不管如何调用,onCreate始终只会调用一次,对应startService调用多少次,Service的onStart便会调用多少次。调用unbindService将不会停止Service,而必须调用 stopService 或 Service的 stopSelf 来停止服务。

当服务被停止时清除服务:

当一个Service被终止(1、调用stopService;2、调用stopSelf;3、不再有绑定的连接(没有被启动))时,onDestroy方法将会被调用,在这里你应当做一些清除工作,如停止在Service中创建并运行的线程。

service使用的时候应当注意的事情

1、bindService 绑定到Service的时候,你就应当保证在某处调用 unbindService 解除绑定(尽管 Activity 被 finish 的时候绑定会自解除,并且Service会自动停止);

2、使用 startService 启动服务之后,一定要使用 stopService停止服务,不管你是否使用bindService;

3、同时使用 startService 与 bindService 要注意到,Service 的终止,需要unbindService与stopService同时调用,才能终止 Service,不管 startService 与 bindService 的调用顺序,如果先调用 unbindService 此时服务不会自动终止,再调用 stopService 之后服务才会停止,如果先调用 stopService 此时服务也不会终止,而再调用 unbindService 或者 之前调用 bindService 的 Context 不存在了(如Activity 被 finish 的时候)之后服务才会自动停止;

4、当在旋转手机屏幕的时候,当手机屏幕在“横”“竖”变换时,此时如果你的 Activity 如果会自动旋转的话,旋转其实是 Activity 的重新创建,因此旋转之前的使用 bindService 建立的连接便会断开(Context 不存在了),对应服务的生命周期与上述相同。

5、在 sdk 2.0 及其以后的版本中,对应的 onStart 已经被否决变为了 onStartCommand,不过之前的 onStart 任然有效。这意味着,如果你开发的应用程序用的 sdk 为 2.0 及其以后的版本,那么你应当使用 onStartCommand 而不是 onStart

在 AndroidManifest.xml 里 Service 元素的常见选项

android:name  -------------  服务类名

android:label  --------------  服务的名字,如果此项不设置,那么默认显示的服务名则为类名

android:icon  --------------  服务的图标

android:permission  -------  申明此服务的权限,这意味着只有提供了该权限的应用才能控制或连接此服务

android:process  ----------  表示该服务是否运行在另外一个进程,如果设置了此项,那么将会在包名后面加上这段字符串表示另一进程的名字

android:enabled  ----------  如果此项设置为 true,那么 Service 将会默认被系统启动,不设置默认此项为 false

android:exported  ---------  表示该服务是否能够被其他应用程序所控制或连接,不设置默认此项为 false

  • 本地服务 Local Service 用于应用程序内部。
  • 它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
      用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
  • 远程服务 Remote Service 用于android系统内部的应用程序之间。
      它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。
      可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。

播放音乐的实现方法 - 简单实现逻辑

一、首先定义一个接口,将要暴露出来操作的方法声明出来

//把想暴露的方法都定义在这里
public interface Iservice {// 播放音乐的方法public void callPlayMusic();//暂停音乐播放的方法public void callPauseMusic();// 重新播放音乐的方法public void callRePlayMusic();
}

二、定义一个服务,并在清单文件中进行相关配制

public class MusicService extends Service {//(2)把我们定义的中间人对象在这里返回@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}// 播放音乐的方法public void playMusic() {System.out.println("音乐播放了 ...");}// 暂停音乐的方法public void pauseMusic() {System.out.println("音乐暂停了 ...");}// 继续播放音乐的方法public void replayMusic() {System.out.println("音乐继续播放了 ...");}

三、定义中间人对象

我们要进行Activity中操作服务中的方法,所以要定义一个中间人对象,继承Binder并实现我们定义的接口,并在相关方法中操作服务中的相关方法,

 //(1)定义中间人对象 private class MyBinder extends Binder implements Iservice{@Overridepublic void callPlayMusic() {//调用播放音乐的方法 playMusic();}@Overridepublic void callPauseMusic() {//调用暂停音乐的方法pauseMusic();}@Overridepublic void callRePlayMusic() {//调用继续播放的方法replayMusic();}}

四、 定义出来中间人对象后,在服务中的

@Overridepublic IBinder onBind(Intent intent) {return new MyBinder;}

将中间人对象返回;

五、接下来就是在Activity中的使用

首先监听服务,获取中间人对象,当服务连接成功后

//监视服务的状态private class MyConn implements ServiceConnection{//当服务连接成功的时候调用  获取我们定义的中间人对象(IBinder)@Overridepublic void onServiceConnected(ComponentName name, IBinder iBinder) {//获取我们定义的中间人对象 iBinder= (Iservice) iBinder;}@Overridepublic void onServiceDisconnected(ComponentName name) {}}

那么在Activity的方法中

@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//(1)先调用startService() ,开户服务,服务就会在后台长期运行 Intent intent = new Intent(this,MusicService.class);startService(intent);//(2)调用bindservice()方法 可以获取我们定义的中间人对象 间接调用服务里面的方法conn = new MyConn();bindService(intent, conn, BIND_AUTO_CREATE);

然后我们就可以通过中间人对象来调用服务中的方法

 // 点击按钮 播放音乐public void click1(View v) {iBinder.callPlayMusic();}// 点击按钮 暂停音乐public void click2(View v) {iBinder.callPauseMusic();}// 点击按钮 继续播放public void click3(View v) {iBinder.callRePlayMusic();}

最后是要解绑服务的操作

@Overrideprotected void onDestroy() {//当Activity销毁的时候 解绑服务 unbindService(conn);super.onDestroy();}

播放音乐的具体实现过程

首先创建一个接口,接口里面暴露出我们要在activity中操作音乐播放的方法

//把想暴露的方法都定义在这里
public interface Iservice {//播放音乐的方法public void callPlayMusic();//暂停音乐的方法public void callPauseMusic();//重新播放音乐的方法public void callRePlayMusic();//设置音乐播放的位置public void callSetSeekPosition(int position);}

然后定义一个中间人对象,继承Binder并来实现我们所定义的接口;

这个中间人对象用来让Activity来操作服务中的方法

 //(1)定义中间人对象 private class MyBinder extends Binder implements Iservice{@Overridepublic void callPlayMusic() {//调用播放音乐的方法 playMusic();}@Overridepublic void callPauseMusic() {//调用暂停音乐的方法pauseMusic();}@Overridepublic void callRePlayMusic() {//调用继续播放的方法replayMusic();}@Overridepublic void callSetSeekPosition(int position) {//设置音乐播放指定位置的方法setSeekPosition(position);}}

然后定义一个服务,里面实现播放音乐的逻辑,并关联我们定义的中间人对象

private MediaPlayer player;private Timer timer;private TimerTask task;//(2)把我们定义的中间人对象在这里返回@Overridepublic IBinder onBind(Intent intent) {return new MyBinder();}//当服务第一次开启的时候回执行这个方法@Overridepublic void onCreate() {//(1)创建meidaplayer 实例 player = new  MediaPlayer();super.onCreate();}@Overridepublic void onDestroy() {super.onDestroy();}// 播放音乐的方法public void playMusic() {System.out.println("音乐播放了 ...");try {//设置mediaplayer 为 初始化的状态player.reset();//(2) 设置播放的资源  路径可以 是本地路径 也可以是网络路径 player.setDataSource("/mnt/sdcard/xpg.mp3");//(3)准备播放 player.prepare();//(4)开始播放player.start();//(5)更新进度条的进度 updateSeekBar();} catch (Exception e) {e.printStackTrace();}}//更新进度条的逻辑 //通过Handler来传输数据,在Activty中进行seekBar进度条的更新操作private void updateSeekBar() {//[1]获取歌曲总时长 和 当前播放的进度 final int duration = player.getDuration();//timer 定时器 //[2] 一秒钟获取一次当前进度 timer = new Timer();task = new TimerTask() {@Overridepublic void run() {//每隔一秒钟获取一次 当前歌曲的位置 int currentPosition = player.getCurrentPosition();//创建message对象 Message msg = Message.obtain();//创建bundle 对象 实际底层就是mapBundle bundle = new Bundle();bundle.putInt("duration", duration);bundle.putInt("currentPosition", currentPosition);msg.setData(bundle);//发送消息 MainActivity.handler.sendMessage(msg);}};timer.schedule(task, 50, 1000); //50毫秒后 每隔一秒钟执行一次 task//[3]当歌曲播放完成的时候  把timer 和 tast 取消 player.setOnCompletionListener(new OnCompletionListener() {@Overridepublic void onCompletion(MediaPlayer mp) {System.out.println("歌曲播放完了");timer.cancel(); //取消任务task.cancel();}});}// 暂停音乐的方法public void pauseMusic() {System.out.println("音乐暂停了 ...");player.pause(); //音乐暂停了}// 继续播放音乐的方法public void replayMusic() {System.out.println("音乐继续播放了 ...");player.start();}//设置音乐播放指定位置的方法public void setSeekPosition(int position){player.seekTo(position);}

然后在Activity中进行的操作

首先创建服务的监听

 //监视服务的状态private class MyConn implements ServiceConnection{//当服务连接成功的时候调用  获取我们定义的中间人对象(IBinder)@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {//获取我们定义的中间人对象 iservice = (Iservice) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {}}

然后创建Handler

//定义一个handler  ,来接收服务中传输过来的数据public static Handler handler = new Handler(){public void handleMessage(android.os.Message msg) {//(1)获取我们服务中封装传输的数据 Bundle data = msg.getData();int duration = data.getInt("duration");int currentPosition = data.getInt("currentPosition");//(2)设置seekbar的最大进度 seekBar.setMax(duration);//设置当前进度seekBar.setProgress(currentPosition); };};

然后初始化一些相关数据操作

 @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//(1)先调用startService(),开户服务 ,服务就会在后台长期运行 Intent intent = new Intent(this,MusicService.class);startService(intent);//(2)调用bindservice()方法 可以获取我们定义的中间人对象 间接调用服务里面的方法//为了获取我们定义的中间人对象 conn = new MyConn();bindService(intent, conn, BIND_AUTO_CREATE); //(3)找到seekbar 设置当前进度 和 总进度(这是我们显示界面上的控件) seekBar = (SeekBar) findViewById(R.id.seekBar1);//(4)给seekbar设置监听事件 ,用于拖动seekBar来改变音乐播放的进度seekBar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {//当拖动停止的时候调用@Overridepublic void onStopTrackingTouch(SeekBar seekBar) {//调用播放的指定位置的方法 iservice.callSetSeekPosition(seekBar.getProgress());}//刚开始拖动调用@Overridepublic void onStartTrackingTouch(SeekBar seekBar) {}//当进度发生改变的时候调用@Overridepublic void onProgressChanged(SeekBar seekBar, int progress,boolean fromUser) {}});}

然后实现操作音乐播放的具体操作

 // 点击按钮 播放音乐public void click1(View v) {iservice.callPlayMusic();}// 点击按钮 暂停音乐public void click2(View v) {iservice.callPauseMusic();}// 点击按钮 继续播放public void click3(View v) {iservice.callRePlayMusic();}

最后解绑服务

@Overrideprotected void onDestroy() {//当Activity销毁的时候 解绑服务 unbindService(conn);super.onDestroy();}

Android中的service相关推荐

  1. Android 中的 Service 全面总结(转)

    转自:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html# Android 中的 Service 全面总结 1.Service的种 ...

  2. Android中的service全面总结

    文章出处:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 1.Service的种类 按运行地点分类: 类别 区别  优点 缺点 ...

  3. Android 中的 Service 全面总结

    1.Service的种类   按运行地点分类: 类别 区别 优点 缺点 应用 本地服务(Local) 该服务依附在主进程上, 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Loc ...

  4. Android中的Service组件详解

    Service与Activity的区别在于:Service一直在后台运行,他没有用户界面,绝不会到前台来. 一,创建和配置Service 开发Service需要两个步骤:1,继承Service子类,2 ...

  5. Android 中的 Service 全面总结(二)

    4.startService 启动服务 想要用 startService 启动服务,不管Local 还是 Remote 我们需要做的工作都是一样简单.当然要记得在 Androidmanifest.xm ...

  6. 【转】Android 中的 Service 全面总结

    1.Service的种类   按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程上,  服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另 ...

  7. Android中的Service模板,通过Service发送通知并修改通知的提示音

    Sercvice作为android中的四大组件之一,主要用来执行后台耗时任务,比如上传大文件.轮询服务器消息.间断向服务器发送数据.应用处于后台运行时向用户推送通知等等,使用场景多样,但是Servic ...

  8. 【转】Android中保持Service的存活

    这几天一直在准备考试,总算有个半天时间可以休息下,写写博客. 如何让Service keep alive是一个很常见的问题. 在APP开发过程中,需要Service持续提供服务的应用场景太多了,比如闹 ...

  9. Android中保持Service的存活

    这几天一直在准备考试,总算有个半天时间可以休息下,写写博客. 如何让Service keep alive是一个很常见的问题. 在APP开发过程中,需要Service持续提供服务的应用场景太多了,比如闹 ...

  10. Android中保持Service的状态

    关于如何让Service keep alive,我在上篇博客给出的解决方案是:方案一,让服务器端发一个推送,检查Service是否还存活:方案二,将Service独立出来,运行在另一个进程中. 这两个 ...

最新文章

  1. 请求体的方式传参_Angularjs中$http以post请求通过消息体传递参数的实现方法
  2. 程序猿修仙之路--算法之直接插入排序
  3. C# WebBrower1控件提示“该文档已被修改,是否保存修改结果”解决方法 .
  4. Spring JDBC开发
  5. android布局中上下对齐,android – 如何使用相对布局垂直对齐列表中的项?
  6. Spring 这些能升华代码的技巧,可能会让你爱不释手
  7. Project facet Java version 1.7 is not supported.解决方法
  8. python抛硬币正面向上概率_Python-计算抛硬币出现连续10次正面朝上的概率的仿真实验...
  9. Android系统Recovery工作原理之使用update.zip升级过程分析(一)
  10. cookie和session理解
  11. 89C52定时/计数器
  12. 一些 NSArray 的基本操作代码例子
  13. Java实现json对比(递归)
  14. 蛋白质组学技术与药物作用新靶点研究进展
  15. Linux替换压缩包下的文件,Linux下rar及zip压缩包中批量替换某文件脚本
  16. oracle按年同比环比,oracle中sum和case when的结合使用(求同比和环比)
  17. vue el-menu多级菜单递归
  18. linux 使用team实现双网卡绑定单个IP
  19. STM32---定时器的ETR功能
  20. 相亲角、地摊,暗访小县城的夜市

热门文章

  1. 管天管地管空气!谷歌探索用CV估算空气质量
  2. 韩国ETRI提出实时Anchor-Free实例分割算法CenterMask,代码将开源
  3. 资深程序员:Python中你不知道的那些小工具
  4. Python系统学习流程图, 教你一步步学习python
  5. 小白如何学3D建模?从零开始变大神,学习记录手册(必备)
  6. 教程|YOLOX目标检测ncnn实现
  7. 字节跳动 2022 校园招聘研发提前批正式启动!
  8. 刚刚!2020“中国高被引学者” 榜单发布:清华、北大、浙大位居内地前三!
  9. 屏蔽预训练模型的权重。 只训练最后一层的全连接的权重。_轻量化 | 如何让笨重的深度学习模型在移动设备上跑起来?看它!...
  10. 收货详细假地址大全_【肖博数学】考生必看:高中数学三角函数公式大全(史上最全)...