Service是什么

Service(服务)是一个没有用户界面的在后台运行执行耗时操作的应用组件。其他应用组件能够启动Service,并且当用户切换到另外的应用场景,Service将持续在后台运行。另外,一个组件能够绑定到一个service与之交互(IPC机制),例如,一个service可能会处理网络操作,播放音乐,操作文件I/O或者与内容提供者(content 
provider)交互,所有这些活动都是在后台进行。

Service有两种状态,“启动的”和“绑定”

Service默认跑在主线程,所以是在Service里建立子线程而不是建立子线程跑Service。

Service的基本使用

定义一个服务:新建类继承Service类 
onBind方法是必须覆盖的,而其他三个分别是创建时调用,销毁时调用,启动时调用

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

注册Service,同样是在配置文件中:

<service android:name=".MyService" />
  • 1

启动服务和停止服务:

 switch (v.getId()) {
case R.id.button1:
Intent startIntent =new Intent(this,MyService.class);
startService(startIntent);
break;
case R.id.button2:
Intent stopIntent =new Intent(this,MyService.class);
stopService(stopIntent);
break;
}

Service自己结束自己:stopSelf();

如果要服务完成什么功能,写在onStartCommand方法里面即可。

Service与Activity通信:

使用Binder对象可以进行两者通信,方法如下: 
1. 在service里面新建Binder类继承Binder:

class MyBinder extends Binder{
public void MyStart(){
Log.d("Service", "MyStart: MyStart");
}
}
  1. onBind方法中返回这个类的实例
private MyBinder mybinder;
@Override
public IBinder onBind(Intent intent) {
return mybinder;
}
  1. 接下来在活动中调用Service的方法,先绑定服务。 
    绑定用的参数connection;
private MyService.MyBinder myBinder;
private ServiceConnection connection=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//绑定调用
} @Override
public void onServiceDisconnected(ComponentName name) {
//j解绑调用
}
};

绑定服务

case R.id.button3:
Intent bindIntent=new Intent(this,MyService.class);
bindService(bindIntent,connection,BIND_AUTO_CREATE);
break;
case R.id.button4:
unbindService(connection);
break;

调用服务的方法: 
写在onServiceConnected里面:

@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myBinder=(MyService.MyBinder) service;
myBinder.MyStart();
}

服务的生命周期

 
通过这个图可以看到,两种启动service的方式以及他们的生命周期,bind service的不同之处在于当绑定的组件销毁后,对应的service也就被kill了。service的声明周期相比与activity的简单了许多,只要好好理解两种启动service方式的异同就行。




1.Service的基本认识

1.1 Service是什么?

  Service(服务)是一个一种可以在后台执行长时间运行操作而没有用户界面的组件。它运行于UI线程,因此不能进行耗时的操作。

1.2 Service和Thread的区别

  Service的运行是在UI线程当中的,是绝对绝对不能进行耗时操作的,而Thread开启的子线程则可以进行耗时操作,但是Thread开启的子线程是不能直接对UI进行操作的,否则极有可能发生直接让程序崩掉,这就是它们的区别。

2.启动Service的2种方式

2.1 startService()方法开启Service

  步骤: 
  a.定义一个类继承Service。 
  b.在AndroidManifest.xml文件中配置该Service。 
  c.使用Context的startService(Intent)方法启动该Service。 
  d.不再使用该Service时,调用Context的stopService(Intent)方法停止该Service。

2.2 bindService方法开启Service(Activity与Service绑定)

  步骤: 
  a.创建BinderService服务端,继承自Service并在类中创建一个实现IBinder接口的实现实例对象并提供公共方法给客户端调用。 
  b.从onBind()回调方法返回此Binder实例。 
  c.在客户端中,从onServiceConnected回调方法接收Binder,并使用提供的方法调用绑定服务。

3.Service的生命周期

  服务的生命周期有两种,因为服务可以跟Activity绑定起来,也可以不绑定,Activity和服务进行通信的话,是需要把服务和Activity进行绑定的。因此服务的生命周期分为未绑定Activity的和绑定Activity的。

没有绑定Activity的服务生命周期图:

绑定Activity的服务生命周期图:

1.通过Intent和startService()方法启动了一个服务,接下来执行onCreate()方法,首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。如果服务已在运行,则不会调用此方法。

2.当另一个组件(如 Activity)通过调用 startService() 请求启动服务时,系统将调用此方法。一旦执行此方法,服务即会启动并可在后台无限期运行。 如果您实现此方法,则在服务工作完成后,需要由您通过调用 stopSelf() 或 stopService() 来停止服务。(如果您只想提供绑定,则无需实现此方法。)

3.服务开始处于运行状态。

4.某个操作导致服务停止,比如执行了方法stopService(),那么服务接下来会执行onDestory()销毁。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等。 这是服务接收的最后一个调用。

5.服务被完全销毁,下一步就是等待被垃圾回收器回收了。

6.通过Intent和bindService()方法启动了一个服务,接下来会执行onCreate()方法,首次创建服务时,系统将调用此方法来执行一次性设置程序(在调用 onStartCommand() 或 onBind() 之前)。如果服务已在运行,则不会调用此方法。

7.当另一个组件想通过调用 bindService() 与服务绑定(例如执行 RPC)时,系统将调用此方法。在此方法的实现中,您必须通过返回 IBinder 提供一个接口,供客户端用来与服务进行通信。请务必实现此方法,但如果您并不希望允许绑定,则应返回 null。

8.服务开始处于运行状态。成功与Activity绑定。

9.某个操作导致服务解除绑定,比如执行了方法unbindService(),那么服务接下来会解除与当前Activity的绑定。接下来服务将面临销毁。

10.服务执行onDestory()方法被销毁。服务应该实现此方法来清理所有资源,如线程、注册的侦听器、接收器等。 这是服务接收的最后一个调用。

11.服务被完全销毁,下一步就是等待被垃圾回收器回收了。

关于服务,总结一下:

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

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

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

d. 当服务被停止时清除服务:当一个Service被终止(1、调用stopService;2、调用stopSelf;3、不再有绑定的连接(没有被启动))时,onDestroy方法将会被调用,在这里你应当做一些清除工作,如停止在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。



Service 与 Thread的区别

  • 结论:ServiceThread 无任何关系
  • 之所以有不少人会把它们联系起来,主要因为Service的后台概念

后台:后台任务运行完全不依赖UI,即使Activity被销毁 / 程序被关闭,只要进程还在,后台任务就可继续运行

  • 关于二者的异同,具体如下图:
 
示意图
  • 注:一般会将 ServiceThread联合着用,即在Service中再创建一个子线程(工作线程)去处理耗时操作逻辑,如下代码:
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//新建工作线程
new Thread(new Runnable() {
@Override
public void run() {
// 开始执行后台任务
}
}).start();
return super.onStartCommand(intent, flags, startId);
} class MyBinder extends Binder {
public void service_connect_Activity() {
//新建工作线程
new Thread(new Runnable() {
@Override
public void run() {
// 执行具体的下载任务
}
}).start();
} }


Android面试三之Service的更多相关文章

  1. Android面试,与Service交互方式

    五种交互方式,分别是:通过广播交互.通过共享文件交互.通过Messenger(信使)交互.通过自定义接口交互.通过AIDL交互.(可能更多) Service与Thread的区别 Thread:Thre ...

  2. Android面试收集录1 Activity+Service

    1.Activity的生命周期 1.1.首先查看一下Activity生命周期经典图片. 在正常情况下,一个Activity从启动到结束会以如下顺序经历整个生命周期: onCreate()->on ...

  3. Android笔记三十四.Service综合实例二

    综合实例2:client訪问远程Service服务 实现:通过一个button来获取远程Service的状态,并显示在两个文本框中. 思路:如果A应用须要与B应用进行通信,调用B应用中的getName ...

  4. Android面试总结 (转)

    1. 下列哪些语句关于内存回收的说明是正确的? (b) A. 程序员必须创建一个线程来释放内存 B. 内存回收程序负责释放无用内存 C. 内存回收程序允许程序员直接释放内存 D. 内存回收程序可以在指 ...

  5. 【Android面试】Android面试题集锦 (陆续更新)(最新2012-6-18) eoe上看到的

    ===============eoeAndroid社区推荐:======================= 1.Android开发新浪面试题[开发者必看哦]下载地址 http://www.eoeand ...

  6. Android面试题目及其答案

    转自:http://blog.csdn.net/wwj_748/article/details/8868640 Android面试题目及其答案 1.Android dvm的进程和Linux的进程, 应 ...

  7. Android面试题目2

    1. 请描述下Activity的声明周期. onCreate->onStart->onRemuse->onPause->onStop->onRestart->onD ...

  8. 百度的android面试总结分析

    今天就是今天上午10点,我接到了百度的电话面试,当然提前和我说了,我的拖延症是有多强烈,以至于我没怎么准备,当然我也想着看看自己的真实水平,在此检讨一下!!!!!!!!!!!!!!!!!!!!!!!! ...

  9. Android面试之高级篇

    结合自己之前去很多大公司的面试经历和自己面别人的一些题,这里做一些总结,Android面试中常见的面试题. 1,Android的Handler运行机制 要解释Handler的运行机制就要讲几个对象:M ...

随机推荐

  1. HALCON里面的一维测量。

    第一步:将图片导入, 拿到图片的名字 和窗口的句柄 第二步:创建一个测量区域.这个测量区域是一个矩形,假设他的名字叫A gen_measure_rectangle2 (TmpCtrl_Row,//输入 ...

  2. Selenium2.0 Webdriver 随笔

    Webdriver can't action the element when the element is out of view 1. Scroll to the element use Java ...

  3. Portal系统中当切换学生时仍旧停留在当前页面的实现方法

    一.BaseController.cs文件 1.OnActionExecuting方法,该方法可以被各子Controller重写 protected override void OnActionExe ...

  4. spark-sql做ETL时遇到的两个问题

    项目中使用spark-sql来作ETL,遇到两个问题,记录一下. 问题1: spark-sql –master yarn –hiveconf load_date=`date –d ..`  -e 'i ...

  5. Docker+.Net Core 的那些事儿-1.准备工作

    1.下载centos 地址:https://www.centos.org/download/ 我使用的是DVD ISO,这么做的目的是为了在之后的docker填坑的路上,方便使用centos中Fire ...

  6. cocos2d-x项目中如何避免增加一个cpp就必须在工程android.mk文件去添加引用

    LOCAL_SRC_FILES := hellocpp/main.cpp \       ../../Classes/AppDelegate.cpp \ ../../Classes/HelloWorl ...

  7. 【转】html之file标签 --- 图片上传前预览 -- FileReader

    记得以前做网站时,曾经需要实现一个图片上传到服务器前,先预览的功能.当时用html的<input type="file"/>标签一直实现不了,最后舍弃了这个标签,使用了 ...

  8. Akka in action (第一章 介绍Akka)

    在本章 概述Akka 了解Actors和Actor系统 Akka的适用范围 在第一章中,会介绍给你Akk的个方面,它能做什么,与现有的解决方案有那些不同.重点关注Akka有哪些功能和使用范围和强大的并 ...

  9. 读写文件时0A转化为0D 0A

    转自:http://www.cnblogs.com/congdiaodiao/p/4529785.html 用C++写东西,需要往文件里写数据,很简单的代码,大概是这个样子: #include < ...

  10. CSS Outline(轮廓)

    CSS Outline(轮廓) 一.CSS 轮廓(outline) 轮廓(outline)是绘制于元素周围的一条线,位于边框边缘的外围,可起到突出元素的作用. CSS outline 属性规定元素轮廓 ...