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

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

其中涉及到了Service的两种状态:(Started)、(Bound)

  1. Started:

    通过startService()启动的服务处于“启动的”状态,一旦启动,service就在后台运行,即使启动它的应用组件已经被销毁了。通常started状态的service执行单任务并且不返回任何结果给启动者。比如当下载或上传一个文件,当这项操作完成时,service应该停止它本身。

  2. Bound:

    “绑定”状态的service,通过调用bindService()来启动,一个绑定的service提供一个允许组件与service交互的接口,可以发送请求、获取返回结果,还可以通过夸进程通信来交互(IPC)。绑定的service只有当应用组件绑定后才能运行,多个组件可以绑定一个service,当调用unbind()方法时,这个service就会被销毁了。

    注意:

    a.一个服务在进程中的主线程运行——一个服务不会创建自己的线程,也不会在另外的进程运行。

    b.还有就是不要把Service理解成线程,你可以把 Service 想象成一种消息服务,而你可以在任何有 Context 的地方调用 Context.startService、Context.stopService、Context.bindService,Context.unbindService,来控制它,你也可以在 Service 里注册 BroadcastReceiver,在其他地方通过发送 broadcast 来控制它,当然这些都是 Thread 做不到的。举个简单的小例子:如果你的 Thread 需要不停地隔一段时间就要连接服务器做某种同步的话,该 Thread 需要在 Activity 没有start的时候也在运行。这个时候当你 start 一个 Activity 就没有办法在该 Activity 里面控制之前创建的 Thread。因此你便需要创建并启动一个 Service ,在 Service 里面创建、运行并控制该 Thread,这样便解决了该问题(因为任何 Activity 都可以控制同一 Service,而系统也只会创建一个对应 Service 的实例)。

具体例子:在布局文件中添加两个按钮(启动服务,停止服务),添加点击事件(具体findById获取,再添加监听事件)

创建一个Service

package com.example.test_myservice_demo01;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MyService extends Service {
    public MyService() {
    }

@Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }

@Override
    public void onCreate() {
        super.onCreate();
        System.out.println("创建服务");
    }

@Override
    public int onStartCommand(Intent intent,int flags, int startId) {
        System.out.println("启动服务...");      //这里实现服务的核心业务
        for (int i=0;i<50;i++){
            System.out.println("i="+i);
        }
        return super.onStartCommand(intent, flags, startId);
    }

@Override
    public void onDestroy() {
        System.out.println("停止服务");
        super.onDestroy();
    }
}

MainActivity文件

...

public void onClick(View v) {
    switch (v.getId()){
        case R.id.button_start:
            Intent startIntent = new Intent(this,MyService.class);
            startService(startIntent);     //启动服务
            break;
        case R.id.button_stop:
            Intent stopIntent = new Intent(this,MyService.class);
            stopService(stopIntent);   //停止服务
            break;

default:
            break;
    }
}

manifest清单文件中可以看到:

<service
    android:name=".MyService"
    android:enabled="true"
    android:exported="true" />

实验结果:如果不点击停止服务,就会一直在运行状态,有什么办法可以能让服务停止下来,只需要在MyService的任何位置调用stopSelf()就能停止服务。

04-17 06:12:36.755 2909-2909/com.example.test_myservice_demo01 I/System.out: 创建服务
04-17 06:12:36.755 2909-2909/com.example.test_myservice_demo01 I/System.out: 启动服务...
04-17 06:12:36.755 2909-2909/com.example.test_myservice_demo01 I/System.out: i=0
04-17 06:12:36.756 2909-2909/com.example.test_myservice_demo01 I/System.out: i=1
04-17 06:12:36.756 2909-2909/com.example.test_myservice_demo01 I/System.out: i=2
04-17 06:12:36.756 2909-2909/com.example.test_myservice_demo01 I/System.out: i=3

...
04-17 06:12:36.757 2909-2909/com.example.test_myservice_demo01 I/System.out: i=47
04-17 06:12:36.757 2909-2909/com.example.test_myservice_demo01 I/System.out: i=48
04-17 06:12:36.757 2909-2909/com.example.test_myservice_demo01 I/System.out: i=49

点击停止按钮后之后
04-17 06:12:43.282 2909-2909/com.example.test_myservice_demo01 I/System.out: 停止服务

...

IntentService服务

这是一个Service的子类,IntentService使用队列的方式将请求的Intent加入队列,然后开启一个worker thread(线程)来处理队列中的Intent,对于异步的startService请求,IntentService会处理完成一个之后再处理第二个,每一个请求都会在一个单独的worker thread中处理,不会阻塞应用程序的主线程,这里就给我们提供了一个思路,如果有耗时的操作与其在Service里面开启新线程还不如使用IntentService来处理耗时操作。而在一般的继承Service里面如果要进行耗时操作就必须另开线程,但是使用IntentService就可以直接在里面进行耗时操作,因为默认实现了一个worker thread。对于异步的startService请求,IntentService会处理完成一个之后再处理第二个。

例子:

Service类

package com.example.test_myservice_demo01;
import android.app.IntentService;
import android.content.Intent;
/**
 * An {@link IntentService} subclass for handling asynchronous task requests in
 * a service on a separate handler thread.
 * <p>
 * TODO: Customize class - update intent actions and extra parameters.
 * 内部类只有一个工作线程来完成耗时操作,只需要实现HandleIntent方法就行
 */
public class MyIntentService extends IntentService {
    public MyIntentService() {
        super("MyIntentService");
    }

@Override
    protected void onHandleIntent(Intent intent) {
        System.out.println(intent.getStringExtra("info"));
        for (int i =0;i<15;i++){
            System.out.println("onHandleIntent-"+i+"-"+Thread.currentThread().getName());
            try {
                Thread.sleep(500);  //模拟延迟
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
//            if (i==10){
//                stopSelf(); //如果添加,便会停止服务
//                break;
//            }
        }
    }
}

MainActivity同上加上一个点击按钮

case R.id.button_3:
    Intent startIntentService = new Intent(this,MyIntentService.class);
    startIntentService.putExtra("info","这个是 我的第一个IntentService");
    startService(startIntentService);
    break;

-----------------分割线---------------------------

Bound:还有就是绑定服务、解绑

不同于以上服务,在MainActivity中加按钮点击事件(bind,unbind)

case R.id.button_bind:
    Intent intent = new Intent(this,MyBoundService.class);
    //异步
    bindService(intent,connection, Context.BIND_AUTO_CREATE);            //绑定服务
    break;
case R.id.button_unbind:
    unbindService(connection);                                  //解除服务
    break;

还需要:

//绑定服务的连接回调方法
private ServiceConnection connection = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        //绑定成功后回调方法
        downloadBinder = (MyBoundService.DownloadBinder) service;
        downloadBinder.startDownload();
        downloadBinder.getProgress();
    }
    @Override
    public void onServiceDisconnected(ComponentName name) {
        //服务异常调用
    }
};

Service类:

package com.example.test_myservice_demo01;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyBoundService extends Service {
    private DownloadBinder mBinder = new DownloadBinder();
    class DownloadBinder extends Binder{
        public void startDownload(){
            Log.d("MyService","startDownload executed");
        }
        public int getProgress(){
            Log.d("MyService","getProgress executed");
         return 0;
        }
    }
    public MyBoundService() {
    }
    @Override
    public void onCreate() {
        super.onCreate();
    }

@Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        return mBinder;
//        throw new UnsupportedOperationException("Not yet implemented");
    }

@Override
    public boolean onUnbind(Intent intent) {
        System.out.println("已经解除绑定");
        return super.onUnbind(intent);
    }

@Override
    public void onDestroy() {
        super.onDestroy();
    }
}

实验结果:

绑定:

04-17 06:50:08.346 23840-23840/com.example.test_myservice_demo01 D/MyService: startDownload executed

04-17 06:50:08.346 23840-23840/com.example.test_myservice_demo01 D/MyService: getProgress executed

解绑:

04-17 06:50:58.931 23840-23840/com.example.test_myservice_demo01 I/System.out: 已经解除绑定

Android——Service介绍与例子的更多相关文章

  1. Android service介绍和启动方式

    1.Android service的作用: service通常是用来处理一些耗时操作,或后台执行不提供用户交互界面的操作,例如:下载.播放音乐. 2.Android service的生命周期: ser ...

  2. android Service介绍

    一.简介 android中service(服务)运行于后台,没有界面.和其他组件一样,service也运行在主线程中,因此不能用它来做耗时的请求或者动作.可以在服务中开启线程,在线程中做耗时操作.可以 ...

  3. Android Service总结02 service介绍

    Android Service总结02 service介绍 版本 版本说明 发布时间 发布人 V1.0 介绍了Service的种类,常用API,生命周期等内容. 2013-03-16 Skywang ...

  4. Android Service完全解析,关于服务你所需知道的一切(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  5. Android Service(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  6. 【Android】详解Android Service

    目录结构: contents structure [+] Service简单概述 Service在清单文件中的声明 Service启动服务 Service绑定服务 扩展Binder类 使用Messen ...

  7. Android Service总结03 之被启动的服务 -- Started Service

    Android Service总结03 之被启动的服务 -- Started Service 版本 版本说明 发布时间 发布人 V1.0 添加了Service的介绍和示例 2013-03-17 Sky ...

  8. Android Service完全解析,关于服务你所需知道的一切(上)

    转载请注明出处:http://blog.csdn.net/guolin_blog/article/details/11952435 相信大多数朋友对Service这个名词都不会陌生,没错,一个老练的A ...

  9. [转]Android Service完全解析,关于服务你所需知道的一切

      目录(?)[+] Android Service完全解析,关于服务你所需知道的一切(上) 分类: Android疑难解析2013-10-31 08:10 6451人阅读 评论(39) 收藏 举报 ...

随机推荐

  1. 想要快速上手 Spring Boot?看这些教程就足够了!

    1.项目名称:分布式敏捷开发系统架构 项目简介:基于 Spring + SpringMVC + Mybatis 分布式敏捷开发系统架构,提供整套公共微服务服务模块:集中权限管理(单点登录).内容管理. ...

  2. flashfxp软件设置并关联默认编辑器

    flashfxp是一款优秀的ftp应用软件,作为程序员,有时候一点小的改动,在线编辑是很方便的选择,但是flashfxp自带的编辑器像记事本一样,非常不好用.那么怎么设置关联到本地的编辑器,比如设置成 ...

  3. day14(2)---列表推导式、生成器推导式、字典推导式、三元表达式

    一.列表推导式: ls = [元素表达式 for i in 可迭代对象 if 筛选条件] 案例: # -*- coding: utf-8 -*- '''列表生成式练习''' # 练习一(三元表达式): ...

  4. linux进程管理总结

    目录 一.进程相关的概念 二.关闭会话时子进程进程被杀死 三.nohup的原理 四.setsid原理 五.daemon &和守护进程的区别 六.服务进程为什么要fork两次 七.systemd ...

  5. keras神经网络三个例子

    keras构造神经网络,非常之方便!以后就它了.本文给出了三个例子,都是普通的神经网络 例一.离散输出,单标签.多分类 例二.图像识别,单标签.多分类.没有用到卷积神经网络(CNN) 例三.时序预测, ...

  6. 封装HttpUrlConnection开箱即用

    因为经常用到 便写出来方边使用 直接复制本类即可 import java.io.*; import java.net.HttpURLConnection; import java.net.URL; i ...

  7. 深入理解Redis Cluster

    Redis Cluster采用虚拟槽分区,所有的key根据哈希函数映射到0~16383槽内,计算公式: slot = CRC16(key) & 16383 每个节点负责维护一部分槽以及槽所映射 ...

  8. 一起学习造轮子(三):从零开始写一个React-Redux

    本文是一起学习造轮子系列的第三篇,本篇我们将从零开始写一个React-Redux,本系列文章将会选取一些前端比较经典的轮子进行源码分析,并且从零开始逐步实现,本系列将会学习Promises/A+,Re ...

  9. H5 62-浮动元素字围现象

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. 关于oracle设置主键自增的问题

    关于orcale设置主键自增的问题 关于主键Oracle中并没有提供一个直接的语句设置,对于这个oralce一般都是用序列和触发器来实现 一下又两种方法来实现 一 ,不使用触发器 创建序列: crea ...