Service简介 demos

extends:http://blog.csdn.net/ithomer/article/details/7364024

一、 Service简介

Service是android 系统中的四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互。service可以在很多场合的应用中使用,比如播放多媒体的时候用户启动了其他Activity这个时候程序要在后台继续播放,比如检测SD卡上文件的变化,再或者在后台记录你地理信息位置的改变等等,总之服务总是藏在后台的。

Service的启动有两种方式:context.startService() 和 context.bindService()

 

二、 Service启动流程

context.startService() 启动流程:

context.startService()  -> onCreate()  -> onStart()  -> Service running  -> context.stopService()  -> onDestroy()  -> Service stop

如果Service还没有运行,则android先调用onCreate(),然后调用onStart();

如果Service已经运行,则只调用onStart(),所以一个Service的onStart方法可能会重复调用多次。

如果stopService的时候会直接onDestroy,如果是调用者自己直接退出而没有调用stopService的话,Service会一直在后台运行,该Service的调用者再启动起来后可以通过stopService关闭Service。

所以调用startService的生命周期为:onCreate --> onStart (可多次调用) --> onDestroy

context.bindService()启动流程:

context.bindService()  -> onCreate()  -> onBind()  -> Service running  -> onUnbind()  -> onDestroy()  -> Service stop

onBind()将返回给客户端一个IBind接口实例,IBind允许客户端回调服务的方法,比如得到Service的实例、运行状态或其他操作。这个时候把调用者(Context,例如Activity)会和Service绑定在一起,Context退出了,Srevice就会调用onUnbind->onDestroy相应退出。

所以调用bindService的生命周期为:onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory。

在Service每一次的开启关闭过程中,只有onStart可被多次调用(通过多次startService调用),其他onCreate,onBind,onUnbind,onDestory在一个生命周期中只能被调用一次。

三、 Service生命周期 

Service的生命周期并不像Activity那么复杂,它只继承了onCreate()、onStart()、onDestroy()三个方法

当我们第一次启动Service时,先后调用了onCreate()、onStart()这两个方法;当停止Service时,则执行onDestroy()方法。

这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。

它可以通过Service.stopSelf()方法或者Service.stopSelfResult()方法来停止自己,只要调用一次stopService()方法便可以停止服务,无论调用了多少次的启动服务方法。

四、 Service示例

下面我做了一个简单的音乐播放的应用,分别使用startService和bindService来启动本地的服务。

Activity 

public class PlayMusicService extends Activity implements OnClickListener {  

    private Button playBtn;
    private Button stopBtn;
    private Button pauseBtn;
    private Button exitBtn;
    private Button closeBtn;  

    private Intent intent;  

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.music_service);  

        playBtn = (Button) findViewById(R.id.play);
        stopBtn = (Button) findViewById(R.id.stop);
        pauseBtn = (Button) findViewById(R.id.pause);
        exitBtn = (Button) findViewById(R.id.exit);
        closeBtn = (Button) findViewById(R.id.close);  

        playBtn.setOnClickListener(this);
        stopBtn.setOnClickListener(this);
        pauseBtn.setOnClickListener(this);
        exitBtn.setOnClickListener(this);
        closeBtn.setOnClickListener(this);  

    }  

    @Override
    public void onClick(View v) {
        int op = -1;
        intent = new Intent("com.homer.service.musicService");  

        switch (v.getId()) {
        case R.id.play:                             // play music
            op = 1;
            break;
        case R.id.stop:                             // stop music
            op = 2;
            break;
        case R.id.pause:                            // pause music
            op = 3;
            break;
        case R.id.close:                            // close activity
            this.finish();
            break;
        case R.id.exit:                             // stopService
            op = 4;
            stopService(intent);
            this.finish();
            break;
        }  

        Bundle bundle = new Bundle();
        bundle.putInt("op", op);
        intent.putExtras(bundle);  

        startService(intent);                           // startService
    }  

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

        if(intent != null){
            stopService(intent);
        }
    }
}
 

Service

public class MusicService extends Service {
    private static final String TAG = "MyService";  

    private MediaPlayer mediaPlayer;  

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }  

    @Override
    public void onCreate() {
        Log.v(TAG, "onCreate");
        Toast.makeText(this, "show media player", Toast.LENGTH_SHORT).show();  

        if (mediaPlayer == null) {
            mediaPlayer = MediaPlayer.create(this, R.raw.tmp);
            mediaPlayer.setLooping(false);
        }
    }  

    @Override
    public void onDestroy() {
        Log.v(TAG, "onDestroy");
        Toast.makeText(this, "stop media player", Toast.LENGTH_SHORT);
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
        }
    }  

    @Override
    public void onStart(Intent intent, int startId) {
        Log.v(TAG, "onStart");
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            if (bundle != null) {
                int op = bundle.getInt("op");
                switch (op) {
                case 1:
                    play();
                    break;
                case 2:
                    stop();
                    break;
                case 3:
                    pause();
                    break;
                }
            }
        }
    }  

    public void play() {
        if (!mediaPlayer.isPlaying()) {
            mediaPlayer.start();
        }
    }  

    public void pause() {
        if (mediaPlayer != null && mediaPlayer.isPlaying()) {
            mediaPlayer.pause();
        }
    }  

    public void stop() {
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            try {
                mediaPlayer.prepare();  // 在调用stop后如果需要再次通过start进行播放,需要之前调用prepare函数
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}

AndroidManifest.xml

注册activity

<activity
    android:name=".service.PlayMusicService"
    android:label="@string/app_name" />
 

注册service

<service
    android:name=".service.MusicService"
    android:enabled="true" >
    <intent-filter>
        <action android:name="com.homer.service.musicService" />
    </intent-filter>
</service>  

五、 代码解析

1、Activity中,PlayMusicService中通过重写OnClickListener 接口onClick()方法实现对播放音乐的控制,把音乐各种操作用数字通过Intent传递给service

然后通过构造一个Intent , intent = new Intent("com.homer.service.musicService");

其中,com.homer.service.musicService是 AndroidManifest.xml 对service的定义,即上面“注册service”

2、Activity中,音乐播放的控制,利用Bundle绑定数字op后,通过 startService(intent); 服务后发送出去
Bundle bundle = new Bundle();
bundle.putInt("op", op);
intent.putExtras(bundle);

startService(intent);

3、 Service中,会处理Activity启动的 startService(intent);服务,依次调用service的启动过程:onCreate --> onStart(可多次调用) --> onDestroy

onCreate(),  创建mediaPlayer

onStart(),      通过获取Bundle bundle = intent.getExtras();,提取int op = bundle.getInt("op");,然后执行响应的音乐播放操作

onDestroy(),停止并释放mediaPlayer音乐资源,如果当执行context.stopService()时调用此方法

4、Activity中,onClick()函数中close与exit是执行含义是不同的:

close : 只是执行了this.finish(); 关闭了本Activity窗体,service并没有被关掉,音乐依然会继续在后台播放

exit  : 先调用了stopService(intent); 关闭了service服务,在Service中会调用3中的onDestroy()停止并释放音乐资源,后才执行this.finish(); 关闭了本Activity窗体

源码下载

六、 拓展知识(进程和声明周期)

Android操作系统尝试尽可能长时间的保持应用的进程,但当可用内存很低时最终要移走一部分进程。怎样确定那些程序可以运行,那些要被销毁,Android让每一个进程在一个重要级的基础上运行,重要级低的进程最有可能被淘汰,一共有5级,下面这个列表就是按照重要性排列的:

1 一个前台进程显示的是用户此时需要处理和显示的。下列的条件有任何一个成立,这个进程都被认为是在前台运行的。
        a 与用户正发生交互的。
        b 它控制一个与用户交互的必须的基本的服务。
        c 有一个正在调用生命周期的回调函数的service(如onCreate()、onStar()、onDestroy())
        d 它有一个正在运行onReceive()方法的广播接收对象。
只有少数的前台进程可以在任何给定的时间内运行,销毁他们是系统万不得已的、最后的选择——当内存不够系统继续运行下去时。通常,在这一点上,设备已经达到了内存分页状态,所以杀掉一些前台进程来保证能够响应用户的需求。

2 一个可用进程没有任何前台组件,但它仍然可以影响到用户的界面。下面两种情况发生时,可以称该进程为可用进程。
        它是一个非前台的activity,但对用户仍然可用(onPause()方法已经被调用)这是可能发生的,例如:前台的activity是一个允许上一个activity可见的对话框,即当前activity半透明,能看到前一个activity的界面,它是一个服务于可用activity的服务。

3 一个服务进程是一个通过调用startService()方法启动的服务,并且不属于前两种情况。尽管服务进程没有直接被用户看到,但他们确实是用户所关心的,比如后台播放音乐或网络下载数据。所以系统保证他们的运行,直到不能保证所有的前台可见程序都正常运行时才会终止他们。

4 一个后台进程就是一个非当前正在运行的activity(activity的onStop()方法已经被调用),他们不会对用户体验造成直接的影响,当没有足够内存来运行前台可见程序时,他们将会被终止。通常,后台进程会有很多个在运行,所以他们维护一个LRU最近使用程序列表来保证经常运行的activity能最后一个被终止。如果一个activity正确的实现了生命周期的方法,并且保存它当前状态,杀死这些进程将不会影响到用户体验。

5 一个空线程没有运行任何可用应用程序组,保留他们的唯一原因是为了设立一个缓存机制,来加快组件启动的时间。系统经常杀死这些内存来平衡系统的整个系统的资源,进程缓存和基本核心缓存之间的资源。
Android把进程里优先级最高的activity或服务,作为这个进程的优先级。例如,一个进程拥有一个服务和一个可见的activity,那么这个进程将会被定义为可见进程,而不是服务进程。

此外,如果别的进程依赖某一个进程的话,那么被依赖的进程会提高优先级。一个进程服务于另一个进程,那么提供服务的进程不会低于获得服务的进程。例如,如果进程A的一个内容提供商服务于进程B的一个客户端,或者进程A的一个service被进程B的一个组件绑定,那么进程A至少拥有和进程B一样的优先级,或者更高。

因为一个运行服务的进程的优先级高于运行后台activity的进程,一个activity会准备一个长时间运行的操作来启动一个服务,而不是启动一个线程–尤其是这个操作可能会拖垮这个activity。例如后台播放音乐的同时,通过照相机向服务器发送一张照片,启动一个服务会保证这个操作至少运行在service 进程的优先级下,无论这个activity发生了什么,广播接收者应该作为一个空服务而不是简单的把耗时的操作单独放在一个线程里。

时间: 2024-11-13 12:52:12

Service简介 demos的相关文章

SAP Web Service简介与配置方法

p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-size: 10.5000pt } h1 { margin-top: 17.0000pt; margin-bottom: 16.5000pt; margin-left: 0.0000pt; text-indent: 21.0000pt; page-break-after: avoid; text-al

Amazon SQS(Simple Queue Service) 简介

SQS即Simple Queue Service, 是一个分布式的消息队列服务,使用它非常简单,消息队列服务可以用来buffer burst, 使整个服务异步处理,不要求组件始终可用. 开发人员最初使用 Amazon SQS 时只需用到五个 API: CreateQueue.SendMessage.ReceiveMessage.ChangeMessageVisibility 和 DeleteMessage. Amazon SQS 会尽量保持消息顺序,但是由于队列的分布式特性,SQS无法保证发送消

Web Service 简介

最近使用ODI的工具箱中的ODIInvokeWebService.因此简单了解下WebService的理论知识. 一.Web Service 简介 Web Service就是可编程的URL,使用标准的Internet协议(比如HTTP或 XML)远程可调用的应用程序组件. 二.为什么使用 Web Service? 本质:以标准化的方式实现企业内外各个不同服务系统之间的互调或者集成. Web Service技术,能使得运行在不同机器上的不同应用无须借助附加的.专门的第三方软件或硬件, 就可相互交换

Web Service简介

1.1.Web Service基本概念 Web Service也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术.是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册. XML:(Extensible Markup Language)扩展型可标记语言.面向短期的临时数据处理.面向万维网络,是Soap的基础. Soap:(Simple Object A

Web Service简介(一)

这篇博文,我们对Web Service进行一个简单的介绍和认识,作为Web Service的入门.在学习之前,你需要对HTML和XML有基本的了解,Web Service并不是什么难,而且非常的简单. 什么是Web Service? Web service是应用程序组件,可以被其他应用程序使用,不是框架,甚至不是一种技术, 而只是一种跨平台.跨语言的规范. 为什么要用Web Service? 几年前,Web Service并不流行.由于所有主要的平台均可通过Web浏览器访问web,不同的平台可以

Web Service简介(一)(转)

这篇博文,我们对Web Service进行一个简单的介绍和认识,作为Web Service的入门.在学习之前,你需要对HTML和XML有基本的了解,Web Service并不难,而且非常的简单. 什么是Web Service? Web service是应用程序组件,可以被其他应用程序使用,不是框架,甚至不是一种技术, 而只是一种跨平台.跨语言的规范. 为什么要用Web Service? 几年前,Web Service并不流行.由于所有主要的平台均可通过Web浏览器访问web,不同的平台可以借助W

Web Service简介(RESTful Web Services 第一章笔记)

什么是Web Service 它是一种基于HTTP协议的服务,用户通过发送HTTP请求服务器上的数据,服务器也会把数据放在HTTP响应中返回给请求者. Web Service请求主要由两个部分组成,一是方法信息,二是作用域信息,它们做为区分Web Service的关键因素 方法信息 方法信息用来说明要对数据采用什么样的操作,比如是创建还是删除,是更新还是获取.具体来说有两种方式: 一是把方法信息放在HTTP方法中,这种服务方式是RESTful的:例如用HTTP的GET表示获取数据,DELETE表

android Service简介及启动关闭方式

(1)Service是Android系统中的四大组件之一,和Activity是同一层次的组件:它是一种生命周期较长,没有可视化界面,运行于后台的一种服务:例如,我们听音乐可以使用Service,下载东西可以使用Service,我们还可以用它来记录我们所在地理位置的改变,或者启动一个服务来一直监听某种动作:我们还可以使用Service更新Content Provider,发送Intent以及启动系统的通知等: (2)Service生命周期不太复杂,它只继承了onCreate(),onStartCo

Web API 2 (一)之Web Service简介

Web Service 是什么? Web Service 也叫作XML Web Service,是一种网络化的,分布式的软件系统,通常通过Http交付,可以跨编程语言和操作系统进行远程调用操作,通常情况下,Web Service包括服务本身和客户端,后者也被称为消费者或请求者,可以通过网络访问部署在服务器提供的某种服务(通过调用Web服务对外公开的访问接口).其可以是网页浏览器,一个桌面应用,更甚至是一个没有图形界面的应用程序 图 1.1 一个Web 服务和它的一个客户端 根据定义,Web服务和