博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Service
阅读量:6637 次
发布时间:2019-06-25

本文共 8501 字,大约阅读时间需要 28 分钟。

Service

Service是Android四大组件中与Activity最相似的组件,它们都代表可执行的程序,Service与Activity的区别在于:Service一直在后台运行,它没有用户界面,所以绝不会到前台来。一旦Service被启动起来之后,它就与Activity一样。它完全具有自己的生命周期。关于程序中Activity与Service的选择标准是:如果某个程序组件需要在运行时向用户呈现某种界面,或者该程序需要与用户交互,就需要使用Activity,否则就应该考虑使用Service了。

开发者开发Service的步骤与开发Activity的步骤很像,开发Service组件需要先开发一个Service的子类,然后在AndroidManifest.xml文件中配置该Service,配置时可通过

Service简介

Service组件也是可执行的程序,它也有自己的生命周期。创建、配置Service与创建、配置Activity的过程基本相似。

创建、配置Service

就像开发Activity需要两个步骤,开发Service也需要两个步骤:

  1. 定义一个继承Service的子类。
  2. 在AndroidManifest.xml文件中配置该Service。

Service与Activity还有一点相似之处,它们都是从Context派生出来的,因此它们都可调用Context里定义的如getResources()、getContentResolver()等方法。

与Activity相似的是,Service中也定义了系列生命周期方法,如下所示。

  • abstract IBinder onBind(Intent intent):该方法是Service子类必须实现的方法。该方法返回一个IBinder对象,应用程序可通过该对象与Service组件通信。
  • void onCreate():当该Service第一次被创建后将立即回调该方法。
  • void onDestroy():当该Service被关闭之前将会回调该方法。
  • void onStartCommand(Intent intent, int flags, int startId):该方法的早期版本是void onStart(Intent intent, int startId),每次客户端调用startService(Intent)方法启动该Service时都会回调该方法。
  • boolean onUnbind(Intent intent):当该Service上绑定的所有客户端都断开连接时将会回调该方法。

下面的类定义了第一个Service组件。

public class FirstService extends Service {
public FirstService() { } // 必须实现的方法 @Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } // Service被创建时回调该方法 @Override public void onCreate() { super.onCreate(); System.out.println("Service is Created"); } // Service被启动时回调该方法 @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("Service is Started"); return START_STICKY; } // Service被关闭之前回调 @Override public void onDestroy() { super.onDestroy(); System.out.println("Service is Destroyed"); }}

定义了上面的Service之后,接下来需要在AndroidManifest.xml文件中配置该Service,配置Service使用

从上面的配置片段不难看出,配置Service与配置Activity的差别并不大,只是配置Service使用

启动和停止Service

下面的程序使用Activity作为Service的访问者,该Activity的界面中包含两个按钮,一个按钮用于启动Service,一个按钮用于关闭Service。

该Activity的代码如下。

public class MainActivity extends Activity {
Button start, stop; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.id.stop); // 创建启动Service的Intent final Intent intent = new Intent(); intent.setAction("tk.zongzhankui.firstservice.FIRST_SERVICE"); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startService(intent); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { stopService(intent); } }); }}

每当Service被创建时会回调onCreate方法,每次Service被启动时都会回调onStart方法——多次启动一个已有的Service组件将不会再回调onCreate方法,但每次启动时都会回调onStart方法。

绑定本地Service并与之通信

当程序通过startService()和stopService()启动、关闭Service时,Service与访问者之间基本上不存在太多的关联,因此Service和访问者之间也无法进行通信、数据交换。

如果Service和访问者之间需要进行方法调用或数据交换,则应该使用bindService()和unbindService()方法启动、关闭服务。

Context的bindService()方法的完整方法签名为:bindService(Intent service, ServiceConnection conn, int flags),该方法的三个参数的结束如下。

  • service:该参数通过Intent指定要启动的Service。
  • conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时将回调该ServiceConnection对象的onServiceConnected(ComponentName name, IBinder service)方法;当访问者与Service之间断开连接时将回调该ServiceConnection对象的onServiceDisconnected(ComponentName name)方法。
  • flags:指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定为0(不自动创建)或BIND_AUTO_CREATE(自动创建)。

注意到ServiceConnection对象的onServiceConnected方法中有一个IBinder对象,该对象即可实现与被绑定Service之间的通信。

当开发Service类时,该Service类必须提供一个IBinder onBind(Intent intent)方法,在绑定本地Servcie的情况下,onBind(Intent intent)方法所返回的IBinder对象将会传给ServiceConnection对象里onServiceConnected(ComponentName name, IBinder service)方法的service参数,这样访问者就可通过该IBinder对象与Service进行通信。

实际上开发时通常会采用继承Binder(IBinder的实现类)的方式实现自己的IBinder对象。

下面的程序示范了如何在Activity中绑定本地Service,并获取Service的运行状态。该程序的Service类需要“真正”实现onBind()方法,并让该方法返回一个有效的IBinder对象,该Service类的代码如下。

public class BindService extends Service {
private int count; private boolean quit; // 定义onBinder方法所返回的对象 private MyBinder binder = new MyBinder(); // 通过继承Binder来实现IBinder类 public class MyBinder extends Binder {
public int getCount() { // 获取Service的运行状态:count return count; } } // 必须实现的方法 @Override public IBinder onBind(Intent intent) { System.out.println("Service is Binded"); // 返回IBinder对象 return binder; } // Service被创建时回调该方法 @Override public void onCreate() { super.onCreate(); System.out.println("Service is Created"); // 启动一条线程,动态地修改count状态值 new Thread() { @Override public void run() { while (!quit) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } count++; } } }.start(); } // Service被关闭之前回调 @Override public void onDestroy() { super.onDestroy(); this.quit = true; System.out.println("Service is Destroyed"); } // Service被断开连接时回调该方法 @Override public boolean onUnbind(Intent intent) { System.out.println("Service is Unbinded"); return true; }}

上面Service类的粗体字代码实现了onBind()方法,该方法返回了一个可访问该Service状态数据(count值)的IBinder对象,该对象将被传给该Service的访问者。

上面程序通过继承Binder类实现了一个IBinder对象,这个MyBinder类是Service的内部类,这对于绑定本地Service并与之通信的场景是一种常见的情形。当然也可以为MyBinder类提供一个借口,或把MyBinder类定义成一个外部类的形式,这无关紧要。

接下来定义一个Activity来绑定该Service,并在该Activity中通过MyBinder对象访问Service的内部状态。该Activity的界面上包含三个按钮,第一个按钮用于绑定Service,第二个按钮用于解除绑定;第三个按钮用于获取Service的运行状态。该Activity的代码如下。

public class MainActivity extends Activity {
Button bind, unbind, getServiceStatus; // 保持所启动的Service的IBinder对象 BindService.MyBinder binder; // 定义一个ServiceConnection对象 private ServiceConnection conn = new ServiceConnection() { // 当该Activity与Service连接成功时回调该方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { System.out.println("--Service Connected--"); // 获取Service的onBind方法所返回的MyBinder对象 binder = (BindService.MyBinder) service; } // 当该Activity与Service断开连接时回调该方法 @Override public void onServiceDisconnected(ComponentName name) { System.out.println("--Service Disconnected--"); } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bind = (Button) findViewById(R.id.bind); unbind = (Button) findViewById(R.id.unbind); getServiceStatus = (Button) findViewById(R.id.getServiceStatus); // 创建启动Service的Intent final Intent intent = new Intent(); // 为Intent设置Action属性 intent.setAction("tk.zongzhankui.bindservice.BIND_SERVICE"); bind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 绑定指定Service bindService(intent, conn, BindService.BIND_AUTO_CREATE); } }); unbind.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 解除绑定Service unbindService(conn); } }); getServiceStatus.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 获取并显示Service的count值 Toast.makeText(MainActivity.this, "Service的count值为:" + binder.getCount(), Toast.LENGTH_LONG).show(); } }); }}

对于Service的onBind()方法所返回的IBinder对象来说,它可被当成该Service组件所返回的回调对象,Service允许客户端通过该IBinder对象来访问Service内部的数据,这样即可实现客户端与Service之间的通信。

与多次调用startService()方法启动Service不同的是,多次调用bindService()方法并不会执行重复绑定。对于前一个实例程序,用户每单击“启动Service”按钮一次,系统就会回调Service的onStart()方法一次;对于这个实例程序,不管用户单击“绑定Service”多少次,系统只会回调Service的onBind()方法一次。

Service的生命周期

随着应用程序启动Service方式的不同,Service的生命周期也略有差异。

这里写图片描述

Service生命周期

转载于:https://www.cnblogs.com/zongzhankui/p/5875321.html

你可能感兴趣的文章
sql server 索引阐述系列八 统计信息
查看>>
阿里云服务器更改时区为utc
查看>>
APP测试流程和测试点
查看>>
ansible实战
查看>>
PowerShell 远程管理之启用和执行命令
查看>>
iOS开发学习笔记 2-5 C语言部分 数组
查看>>
php,redis,centos5安装完全记录
查看>>
×××应用之GRE
查看>>
python笔记第十天 模块
查看>>
iOS开发小技巧--利用运行时得到隐藏的成员变量
查看>>
又晚睡了...
查看>>
Web常见安全漏洞原理及防范-学习笔记
查看>>
JAVASCRIPT
查看>>
python-django
查看>>
Java实现二叉树及相关遍历方式
查看>>
golang学习笔记17 爬虫技术路线图,python,java,nodejs,go语言,scrapy主流框架介绍...
查看>>
android socket 编程总结
查看>>
git checkout 和 git checkout --merge <branch_name>使用
查看>>
大数据应用蓝皮书:未来涉及5个热点领域
查看>>
IDEA Error:java: 未结束的字符串文字
查看>>