目录

Android四大组件:

1. 服务的概念

1.1 概念

1.2 适用场景

1.3 继承结构图

2. 服务的生命周期

2.1 定义

Service拥有自己的生命周期,不会被捆绑,即便Activity销毁之后,Service也不会销毁。

2.2 启动类型

2.3 结构图

2.4 方法

3. 服务的创建

3.1 创建类并继承Service

3.2 注册服务

3.3 服务启动方式

3.3.1 startService方式启动服务

3.3.2 bindService方式启动服务

3.4 bindService案例

3.4.1 bindService使用场景

绑定服务的最大作用就是用来实现对Service执行的任务进行进度监控。

3.4 服务的关闭与解绑方法

3.5 服务的启动模式

3.6 两种启动方法的区别

4 服务的通信

4.1 通信方式



Android四大组件:  

       ActivityServiceBroadcastReceiverContentProvider

--------------------------------------------------------------------------------------------------------------------------------

1. 服务的概念

1.1 概念

Service(服务)是一个长期运行在后台没有用户界面的应用组件,即使切换到另一个应用程序或者后台,服务也可以正常运行。因此,服务适合执行一段时间不需要显示界面的后台耗时操作(需要另启子线程),比如下载网络数据播放音乐等。

Service可以看做是一个没有界面的Activity,因此启动,销毁服务跟开启,销毁Activity类似

Service并不是运行在一个独立的进程当中,而是依赖于创建服务时所在的应用程序进程,即Service运行在主线程中。当某个应用程序进行被杀掉时,所有依赖于该进程的服务都会停止运行

Service并不会自动开启线程,所有的代码都是默认运行在主线程当中的,也就是说,需要在服务的内部手动创建子线程,并在里面执行具体的任务。否则就会出现主线程被阻塞的情况。

Activity启动服务,主要用于响应和处理Activity的事件。Service拥有自己的生命周期,不会被捆绑,即便Activity销毁之后,Service也不会销毁。 支持显式和隐式启动服务。

1.2 适用场景

 1)下载网络数据(在Android3.0之后,只支持子线程下载,因此此功能应该在子线程中启动服务)。

       2)播放音乐。

       3)访问文件、数据库等一些业务逻辑功能,可以让Service来实现。

1.3 继承结构图

比较Service与Activity的继承关系结构图如下:

2. 服务的生命周期

2.1 定义

     Service可以看做是一个没有界面的Activity。Service拥有自己的生命周期,不会被捆绑,即便Activity销毁之后,Service也不会销毁。

2.2 启动类型

服务的启动方式有两种,分别是startService()(启动服务)bindService()(绑定服务)方法。使用不同的方法启动服务,其生命周期也是不同的。服务的启动都是在Activity中进行的。

1.startService()

其他组件调用startService()启动一个Service,一旦启动,Service将一直运行在后台,即便启动

Service的组件已经被destory。但是,Service会在后台执行单独的操作,也并不会给启动它的

组件返回结果。

比如说:一个以启动服务方式的Service执行在后台下载或者上传一个文件的操作,

完成之后,Service自动停止。

2.bindService()

其他组件调用bindService()绑定一个Service,通过绑定方式启动的Service是一个client-server

结构,该Service可以与绑定它的组件进行交互。一个绑定的Service仅在仅有组件与其绑定时才会运行,

多个组件可与一个Service绑定,Service不在与人和网组件绑定时,将会被destory

2.3 结构图

如下图所示:

2.4 方法

1.onCreate() 服务被创建,单例模式,只会创建一次
2.onStartCommand() 服务启动时调用
3.onBind() 绑定时调用,同时会调用onCreate()方法不会调用onStartCommand()方法
4.onUnBind() 解绑时调用 ,同时会调用onDestory()方法
5.onDestory() 销毁时调用

3. 服务的创建

3.1 创建类并继承Service

Service(服务)是Android四大组件之一。创建方式与广播接收者类似。【new】->【Service】,创建的Service如下所示:

public class MyService extends Service{//客户端通过调用bindService()方法启动服务时执行该方法@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}//客户端通过调用startService()方法启动服务时执行该方法,可以执行多次@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}//第一次创建服务时执行的方法,且只执行一次@Overridepublic void onCreate() {super.onCreate();}//客户端调用unBindeService()方法断开服务绑定时执行该方法@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}//服务被销毁时执行的方法,且只执行一次@Overridepublic void onDestroy() {super.onDestroy();}
}

3.2 注册服务

Service创建后,会在清单文件AndroidManifest.xml中进行注册,如下所示:

<application......>..................<serviceandroid:name="com.example.service.MyService"android:enabled="true"android:exported="true"></service>
</application>
<!--name:服务的路径enabled:表示系统是否能够实例化该组件exported:表示该服务是否能够被其他应用程序组件所调用或者交互
-->

3.3 服务启动方式

3.3.1 startService方式启动服务

          startService(Intent intent), 传入Intent对象,通过startService方式启动服务,服务会长期在后台运行,并且服务的状态与开启者的状态没有关系,即便启动服务的组件已经被销毁,服务也依旧会运行

3.3.2 bindService方式启动服务

通过bindService方式启动服务,服务会与组件进行绑定。一个被绑定的服务提供一个客户端与服务器接口,允许组件与服务进行交互发送请求得到结果多个组件可以绑定一个服务,当调用onUnbind()方法时,这个服务就被销毁了,即调用onDestory()方法。

bindService()方法完整名为bindService(Intent service,ServiceConnection conn,int flags),该方法的三个参数解释如下:

 Intent对象 用于指定要启动的Service。
ServiceConnection对象

用于监听调用者与Service之间的连接状态。当调用者与Service连接成功时,

将回调该对象的onServiceConnected(ComponentName name,IBinder service)方法。

断开连接时,将回调该对象的onServiceDisconnected(ComponentName name)方法。

 flag

绑定时是否自动创建Service(如果Service还未创建)。可指定为0,即不自动创建,

也可指定为“BIND_AUTO_CREATE”,即自动创建。

 之所以需要ServiceConnection对象,是为了表示绑定与解绑某个具体Service。

3.4 bindService案例

3.4.1 bindService使用场景

绑定服务的最大作用就是用来实现对Service执行的任务进行进度监控。

 需要使用的两个类如下:

1.ServiceConnection

是一个接口,主要在绑定服务中用于客户端和服务器端链接的,使用ServiceConnection时

通常要重写onServiceConnected()OnServiceDisconnected()方法

2.IBinder  

案例如下,Service类:

public class MyService extends Service{//服务创建@Overridepublic void onCreate() {super.onCreate();}//绑定服务@Nullable@Overridepublic IBinder onBind(Intent intent) {//返回一个Binder对象,Binder继承与IBinderreturn new MyBinder();}//创建服务代理,调用服务中的方法class MyBinder extends Binder{methodInService();}//自定义方法public void methodInService(){}//解绑@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}
}

可以看出,Binder是实现了IBinder接口。从而在Binder类里面可以自定义方法。

Activity类:

public class MainActivity extends AppCompatActivity{private MyServiceConnection connection;  //ServiceConnection对象@Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}//绑定服务public void btnBind(View view){if(connection == null){connection = new MyServiceConnection();}Intent intent = new Intent(this,MyService.class);//绑定服务,BIND_AUTO_CREATE表示绑定时自动创建ServicebindService(intent,connection,BIND_AUTO_CREATE);}//解绑服务public void btnUnbind(View view){if(connection != null){//解绑服务,这里需要传入ServiceConnection对象unbindService(connection);connection = null;}}//调用绑定的服务里面的方法public void btnCallServiceInMethod(View view){}/*** 创建类继承ServiceConnection,用于解绑服务方法调用*/public class MyServiceConnection implements ServiceConnection{//当客户端正常连接这个服务时,成功绑定到服务时调用该方法。注意IBinder参数对象@Overridepublic void onServiceConnected(ComponentName componentName, IBinder iBinder) {//如果成功绑定,iBinder为MyService里面的IBinder对象Log.i("MainActivity","服务绑定成功,内存地址为:"+iBinder.toString());}//当客户端与服务失去连接时调用该方法@Overridepublic void onServiceDisconnected(ComponentName componentName) {//解绑Log.i("MainActivity","服务解绑成功");}}
}

可以看出,onServiceConnected()方法里面的IBinder就是Service里面的onBinder()方法的返回IBinder对象。

3.4 服务的销毁方法

1)通过startService方式启动的服务时,销毁服务方法

         通过stopService(Intent inetnt)方式;

    2)通过bindService方式启动的服务时,销毁服务方法

         通过unbindService(ServiceConnection conn)方式。

3.5 服务的启动模式

1)单例模式:Service在Android中是单例模式,即onCreate()与onDestory()只会被调用一次。

2)重新创建:如果系统发生异常导致服务终止后,如果内存足够,服务所在的进程会重新创建服务。如果是用户主动销毁的,则不会重新创建。

3.6 两种启动方法的区别

在Android中绑定式服务bindService会随着Activity的结束而结束,但是启动式服务startService不受Activity的影响。

4 服务的通信

通过绑定方式开启服务后,服务与Activity是可以通信的,通过Activity可以控制服务进行一些操作。

4.1 通信方式

在Android中,服务的通信方式有两种:本地服务通信远程服务通信。使用这两种方式进行通信时,必须保证服务是以绑定的形式开启的,否则无法进行通信和数据交换

   1)本地服务通信

指的是应用程序内部的通信。首先需要创建一个Service类,该类会提供一个onBind()方法,onBind()方法的返回值是一个IBinder对象,IBinder对象会作为参数传递给ServiceConnection类中的onServiceConnected(ComponentName name,IBinder service)方法,这样访问者就可用通过IBinder对象与Service进行通信。如下图所示:

从上图可以看出,服务在进行通信时实际使用的是IBinder对象,在ServiceConnection类中得到的IBinder对象,通过这个对象可以获取到服务中自定义的方法,执行具体的操作。

     2)远程服务通信

在Android系统中,各个应用程序都运行在自己的进程中,如果想要完成不同进程之间的通信,就需要用到远程服务通信。远程服务通信时通过AIDL(Android Interface Definition Language)实现的,接口定义语言,语法格式简单,与Java中定义接口类似,但存在差异如下:

  》AUDL定义接口的源代码必须以.aidl结尾。

        》AIDL接口中用到的数据类型,除了基本数据类型及String、List、Map、CharSequence之外,其他类型全部都需要导入到包,即使它们在同一个包中。

下面一个音乐播放器案例演示本地服务通信:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/back1"android:orientation="vertical"><EditTextandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/musicplayer_et_inputpath"android:text="Mucis/a.mp3"android:textColor="#FFEEF608"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:layout_gravity="center_vertical"android:gravity="center"android:orientation="horizontal"><TextViewandroid:id="@+id/musicplayer_tv_paly"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="播放"android:textColor="#FFFFFF"android:textSize="18sp"android:drawableTop="@drawable/weibo"android:drawablePadding="3dp"android:gravity="center"/><TextViewandroid:id="@+id/musicplayer_tv_pause"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:text="暂停"android:textColor="#FFFFFF"android:textSize="18sp"android:drawableTop="@drawable/weixin"android:drawablePadding="3dp"android:gravity="center"/></LinearLayout>
</LinearLayout>

Service类:

public class MusicPlayerService extends Service {private static final String TAG = "MucisPalyerService";public MediaPlayer mediaPlayer;public MusicPlayerService() {}class MyBinder extends Binder{//播放音乐public void play(String path){try{if(mediaPlayer == null){//创建一个MediaPlayer播放器mediaPlayer = new MediaPlayer();//指定参数为音频文件mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);//指定播放的路径mediaPlayer.setDataSource(path);//准备播放mediaPlayer.prepare();mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener(){public void onPrepared(MediaPlayer mp){//开始播放mediaPlayer.start();}});}else{//int position = getCurrent}}catch (Exception e){e.printStackTrace();}}//暂停播放public void pause(){if(mediaPlayer != null && mediaPlayer.isPlaying()){mediaPlayer.pause();}else if(mediaPlayer != null && (!mediaPlayer.isPlaying())){mediaPlayer.start();}}}public void onCreate(){super.onCreate();}//获取当前进度public int getCurrentProgress(){if(mediaPlayer != null && mediaPlayer.isPlaying()){return mediaPlayer.getCurrentPosition();}else if(mediaPlayer != null && (!mediaPlayer.isPlaying())){return mediaPlayer.getCurrentPosition();}return 0;}public void onDestory(){if(mediaPlayer != null){mediaPlayer.stop();mediaPlayer.release();mediaPlayer = null;}super.onDestroy();}@Overridepublic IBinder onBind(Intent intent) {//第一步执行onBind方法return new MyBinder();}
}

上述代码使用了MediaPlayer类来实现音乐播放功能,其常用方法如下:

》setAudioStreamType():指定音频文件的类型,必须在prepare()方法之前使用。

        》setDataSource():设置要播放的音频文件的位置,即URI路径,

        》prepare():准备播放,调用此方法会使MediaPlayer进入准备状态。

        》start():开始或继续播放音频。

        》pause():暂停播放音频。

        》seekTo():从指定的位置开始播放音频。

        》release():释放掉与MediaPlayer对象相关的资源。

        》isPlaying():判断当前MediaPlayer是否正在播放音频。

        》getCurrentPosition():获取当前播放音频文件的位置。

Activity类:

public class MusicPlayerActivity extends AppCompatActivity implements View.OnClickListener{private EditText path;private Intent intent;private MyConn conn;MusicPlayerService.MyBinder binder;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.musicplayer_layout);path = (EditText)findViewById(R.id.musicplayer_et_inputpath);findViewById(R.id.musicplayer_tv_paly).setOnClickListener(this);findViewById(R.id.musicplayer_tv_pause).setOnClickListener(this);conn = new MyConn();intent = new Intent(this,MusicPlayerService.class);bindService(intent,conn,BIND_AUTO_CREATE);}private class MyConn implements ServiceConnection{public void onServiceConnected (ComponentName name, IBinder service){binder = (MusicPlayerService.MyBinder)service;}public void onServiceDisconnected(ComponentName name){}}public void onClick(View v) {String pathway = path.getText().toString().trim();File SDPath = Environment.getExternalStorageDirectory();File file = new File(SDPath, pathway);String path = file.getAbsolutePath();switch (v.getId()) {case R.id.musicplayer_tv_paly:if (file.exists() && file.length() > 0) {binder.play(path);} else {Toast.makeText(this, "找不到音乐文件", Toast.LENGTH_SHORT).show();}break;case R.id.musicplayer_tv_pause:binder.pause();break;default:break;}}protected void onDestory(){unbindService(conn);super.onDestroy();}
}

Android开发-Service(服务)相关推荐

  1. Android开发Service之BindService

    前言 一直使用 Qt 来进行桌面端和移动端开发,对 Android 开发并不熟悉,但是项目中往往又经常会用到 Android 原生开发的东西.本次收集了一些关于BindService相关的知识供自己学 ...

  2. Android开发--Service和Activity通过广播传递消息

    Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...

  3. Android 保证Service服务不被杀死的几个方法

    第一章 Service介绍 service服务是一个应用程序的四大组件之一,可以再后台执行长时间运行的操作,不提供用户界面.一个应用程序组件可以启动一个服务,它将继续在后台运行,即使用户切到另一个应用 ...

  4. android 获取Service(服务)的运行状态

    在开发的时候,经常会用到服务,有时候就会用到判断服务的运行状态,下面就创建一个工具类来判断服务是在还在运行. package cn.edu.cqu.mobilesafe.utils;import ja ...

  5. Android开发--Service开启,关闭,绑定,解除

    Android应用程序中有一项非常重要的技术--Service,它没有运行界面,运行在后台,但是有一点非常重要,Service并不是一个单独的进程,同时也不是一个线程,用来处理耗时的动作. Servi ...

  6. android job service,服务保活那些事(Job Service ,JobScheduler)

    Android5.0以上保活 Android5.0之后,很多都是可以被APP杀死,尤其是某机型做服务保活更难.Android5.0之后Android提供了JobService和JobScheduler ...

  7. android中service名词解释,Android中Service(服务)详解

    A service is "bound" when an application component binds to it by calling 通过startService() ...

  8. 收藏 | Android开发从入门到精通系列书籍资料最全攻略!!!(最新更新)

    很多人会私信给我提问,问安卓的学习路线是什么,因为之前没有写过系统的路线图,于是近期花了一些时间,把这块的知识,做成一个体系分享给大家,也算是自己在安卓这边做的一份贡献. 关于安卓如何来学习,安卓入门 ...

  9. Android 项目开发 基于Web Service 服务的中英翻译软件(三) Web Service服务 Ksoap2 项目...

    关于Web Service Android 应用通常是运行手机平台上,手机系统的硬件资源远远比不上PC平台,不管是存储能力还是计算能力,在Android平台上运行一些小的应用时可能的,但对于需要进行大 ...

  10. Android开发之如何保证Service不被杀掉(前台服务)

    序言 最近项目要实现这样一个效果:运行后,要有一个service始终保持在后台运行,不管用户作出什么操作,都要保证service不被kill.参考了现今各种定制版的系统和安全厂商牛虻软件,如何能保证自 ...

最新文章

  1. 转载/VMware Workstation环境下的Linux网络设置/适用于无线网络
  2. EXE与SYS通信(缓冲模式)
  3. java给定_Java – 在给定示例中使用super()
  4. scratch 素材_scratch书籍免费领
  5. SqlServer2008 R2删除数据库时报数据库正在使用的错误
  6. Spring mvc 响应字符串
  7. Unix/Linux的内存映射
  8. FFT【快速傅里叶变换】FWT【快速沃尔什变换】
  9. 关于String的常用方法
  10. win7开机动画_win7系统怎么修改开机动画 win7系统开机动画修改方法
  11. 测试一下你真的理解数据库左连接了吗?
  12. 运放参数的详细解释和分析-part2-如何测量输入偏置电流Ib和输入失调电流Ios
  13. NAND Flash内部结构简介
  14. 四种常见的颜色模式及各自的特点?
  15. 如何批量给图片加水印?
  16. 利用ISA防火墙实现安全快速上网
  17. NFS挂载问题:mount.nfs: access denied by server while mounting 192.168.1.100:/home/rootfs
  18. 我的世界服务器如何做无限箱子,《我的世界》无限存储箱子制作方法 制作流程介绍...
  19. 解决python.exe 无法找到程序入口,无法定位程序输入点
  20. 移动端开发-体检预约

热门文章

  1. 计算机管理里面删打印机就卡住了,打印机任务无法删除怎么办-解决打印机任务无法删除的方法 - 河东软件园...
  2. 如何写好一篇技术型文档?
  3. gitee创建仓库,并将代码上传到gitee上
  4. 大数据培训课(体验) Day02
  5. Internet Explorer 包含五个预定义区域
  6. SWIFT国际清算体系的科普贴
  7. 【C语言每日练习】——3.回文数、特殊回文数(三种方法详解)
  8. HTTP 405Method not allowed
  9. Android 运行程序报错:Unable to execute dex: Multiple dex files define Lcom/baidu/android/pushservice/Push
  10. Excel使用VBA自动调整列宽