Android开发-Service(服务)
目录
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四大组件:
Activity,Service,BroadcastReceiver,ContentProvider。
--------------------------------------------------------------------------------------------------------------------------------
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(服务)相关推荐
- Android开发Service之BindService
前言 一直使用 Qt 来进行桌面端和移动端开发,对 Android 开发并不熟悉,但是项目中往往又经常会用到 Android 原生开发的东西.本次收集了一些关于BindService相关的知识供自己学 ...
- Android开发--Service和Activity通过广播传递消息
Android的Service也运行在主线程,但是在服务里面是没法直接调用更改UI,如果需要服务传递消息给Activity,通过广播是其中的一种方法: 一.在服务里面发送广播 通过intent传送数据 ...
- Android 保证Service服务不被杀死的几个方法
第一章 Service介绍 service服务是一个应用程序的四大组件之一,可以再后台执行长时间运行的操作,不提供用户界面.一个应用程序组件可以启动一个服务,它将继续在后台运行,即使用户切到另一个应用 ...
- android 获取Service(服务)的运行状态
在开发的时候,经常会用到服务,有时候就会用到判断服务的运行状态,下面就创建一个工具类来判断服务是在还在运行. package cn.edu.cqu.mobilesafe.utils;import ja ...
- Android开发--Service开启,关闭,绑定,解除
Android应用程序中有一项非常重要的技术--Service,它没有运行界面,运行在后台,但是有一点非常重要,Service并不是一个单独的进程,同时也不是一个线程,用来处理耗时的动作. Servi ...
- android job service,服务保活那些事(Job Service ,JobScheduler)
Android5.0以上保活 Android5.0之后,很多都是可以被APP杀死,尤其是某机型做服务保活更难.Android5.0之后Android提供了JobService和JobScheduler ...
- android中service名词解释,Android中Service(服务)详解
A service is "bound" when an application component binds to it by calling 通过startService() ...
- 收藏 | Android开发从入门到精通系列书籍资料最全攻略!!!(最新更新)
很多人会私信给我提问,问安卓的学习路线是什么,因为之前没有写过系统的路线图,于是近期花了一些时间,把这块的知识,做成一个体系分享给大家,也算是自己在安卓这边做的一份贡献. 关于安卓如何来学习,安卓入门 ...
- Android 项目开发 基于Web Service 服务的中英翻译软件(三) Web Service服务 Ksoap2 项目...
关于Web Service Android 应用通常是运行手机平台上,手机系统的硬件资源远远比不上PC平台,不管是存储能力还是计算能力,在Android平台上运行一些小的应用时可能的,但对于需要进行大 ...
- Android开发之如何保证Service不被杀掉(前台服务)
序言 最近项目要实现这样一个效果:运行后,要有一个service始终保持在后台运行,不管用户作出什么操作,都要保证service不被kill.参考了现今各种定制版的系统和安全厂商牛虻软件,如何能保证自 ...
最新文章
- 转载/VMware Workstation环境下的Linux网络设置/适用于无线网络
- EXE与SYS通信(缓冲模式)
- java给定_Java – 在给定示例中使用super()
- scratch 素材_scratch书籍免费领
- SqlServer2008 R2删除数据库时报数据库正在使用的错误
- Spring mvc 响应字符串
- Unix/Linux的内存映射
- FFT【快速傅里叶变换】FWT【快速沃尔什变换】
- 关于String的常用方法
- win7开机动画_win7系统怎么修改开机动画 win7系统开机动画修改方法
- 测试一下你真的理解数据库左连接了吗?
- 运放参数的详细解释和分析-part2-如何测量输入偏置电流Ib和输入失调电流Ios
- NAND Flash内部结构简介
- 四种常见的颜色模式及各自的特点?
- 如何批量给图片加水印?
- 利用ISA防火墙实现安全快速上网
- NFS挂载问题:mount.nfs: access denied by server while mounting 192.168.1.100:/home/rootfs
- 我的世界服务器如何做无限箱子,《我的世界》无限存储箱子制作方法 制作流程介绍...
- 解决python.exe 无法找到程序入口,无法定位程序输入点
- 移动端开发-体检预约
热门文章
- 计算机管理里面删打印机就卡住了,打印机任务无法删除怎么办-解决打印机任务无法删除的方法 - 河东软件园...
- 如何写好一篇技术型文档?
- gitee创建仓库,并将代码上传到gitee上
- 大数据培训课(体验) Day02
- Internet Explorer 包含五个预定义区域
- SWIFT国际清算体系的科普贴
- 【C语言每日练习】——3.回文数、特殊回文数(三种方法详解)
- HTTP 405Method not allowed
- Android 运行程序报错:Unable to execute dex: Multiple dex files define Lcom/baidu/android/pushservice/Push
- Excel使用VBA自动调整列宽