Android 回顾Service之Service基础使用

这两天在回顾Android Service方面的知识,趁着记忆没有消退之前,来总结一下。本文主要讲解Service的基本概念与使用、跨进程调用Service、系统常见Service的使用。所以本文的难度微乎其微,仅适用于想回顾Service知识点的同学,或者还不怎么了解Service的同学,至于Service源码之类的东东,等老夫分析研究之后再来分享。

一、Service基础

我相信只要接触过Android开发的人,都或多或少的了解过Service。Service是什么呢?Service是Android四大组件中与Activity最相似的组件,它完全具有自己的生命周期,不过它可没有和Activity一样的华丽外表,它常年在后台默默付出。Service也是可执行的程序,前面说了它有自己的生命周期,其创建于配置过程与Activity极其相似。不仅如此,Activity与Service还有共同的父亲Context,因此它们都可以调用Context里定义的如getResources()、getContentResolver()等方法。

1、Service的简单使用:

开发Service需要两个步骤:(1)定义一个继承Service的子类。(2)在AndroidManifest.xml文件中配置该Service。

在动手开发第一个Service之前,我们先来了解一下Service的系列生命周期方法:

(1)IBinder onBind(Intent intent):该方法是Service子类必须实现的方法。该方法返回一个IBinder对象,应用程序可通过该对象与Service组件通信。

(2)void onCreate():当该Service第一次被创建后将立即回调该方法。

(3)void onDestroy():当该Service被关闭之前将会回调该方法。

(4)void onStartCommand(Intent intent,int flags,int startId):该方法的早期版本是void onStart(Intent intent,int startId),每次客户端调用startService(Intent)方法启动该Service  时都会回调该方法。

(5)boolean onUnbind(Intent intent):当该Service上绑定的所有客户端都断开连接时将会回调该方法。

下面我们来开发我们的第一个Service,代码如下:

package com.gc.servicetest;

import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
/**
 * 注意: onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了,
 * 不管怎样调用startService方法,onCreate()方法都不会再执行。
 * @author Android将军
 *
 */
public class MyService extends Service{

	public static final String TAG=MyService.class.getSimpleName();
	//必须要实现的方法
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.v(TAG, "onBind() executed");
		return null;
	}
      //Service被创建时回调该方法
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.v(TAG, "onCreate() executed");
		Log.v(TAG, "MyService thread id is "+Thread.currentThread().getId());

	}
       //Service被启动时回调该方法
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.v(TAG, "onStartCommand() executed");
		return super.onStartCommand(intent, flags, startId);
	}
       //Service被关闭之前回调该方法
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.v(TAG, "onDestroy() executed");
	}

}

上面这个Service什么也没干——它只是重写了Service组件的onCreate()、onStartCommand()、onDestroy()、onBind()等方法。如果希望Service组件做某些事情,那么只要在onCreate()或onStartCommand()方法中定义相关业务代码即可。开发Service的两个步骤,我们现在已经走完了第一个步骤,下面我们一起走第二步吧。第二步很简单,在AndroidManifest.xml配置Service与在该文件中配置Activity是一样的,只不过标签一个是<service.../>,一个是<activity
.../>。下面给出本次的MyService的配置,代码如下:

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

当两个步骤走完,我们已经开发出了一个Service组件,接下来就可在程序中运行该Service了,Android系统中运行Service有两种方式,如下:

(1)通过Context的startService()方法:通过该方法启动Service,访问者与Service之间没有关联,即使访问者退出了,Service仍然运行。

(2)通过Context的bindService()方法:使用该方法启用Service,访问者与Service绑定在了一起,访问者一旦退出,Service也就终止。

下面我们就来看看如何使用这两种方式来启动我们刚刚开发的Myservice,我们使用Activity作为Service的访问者,该Activity的界面中包含四个按钮,由于代码简单,这里就不再给出其布局文件,下面直接看一下MainActivity的代码,如下

package com.gc.servicetest;

import com.gc.servicetest.MyService.MyBinder;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
/**
 *
 * @author Android将军
 *
 */
public class MainActivity extends Activity implements OnClickListener {

    public static final String TAG=MainActivity.class.getSimpleName();
    private Button mBtnStartService;
    private Button mBtnStopService;
    private Button mBtnBindService;
    private Button mBtnUnBindService;
    private MyService.MyBinder myBinder;

    private ServiceConnection connection=new ServiceConnection() {

		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			Log.v(TAG, "onServiceDisconnected() executed");
			Log.v(TAG, "onServiceDisconnected() executed name"+name);

		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			Log.v(TAG, "onServiceConnected() executed");
			Log.v(TAG, "onServiceConnected() executed name"+name);
			myBinder=(MyBinder) service;
			myBinder.startDownload();
		}
	};
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initUI();
        setListener();
        Log.v(TAG, "MainActivity thread id is "+Thread.currentThread().getId());
    }
	public void initUI()
	{
		mBtnStartService=(Button) findViewById(R.id.start_service);
		mBtnStopService=(Button) findViewById(R.id.stop_service);
		mBtnBindService=(Button) findViewById(R.id.bind_service);
		mBtnUnBindService=(Button) findViewById(R.id.unbind_service);

	}
	public void setListener()
	{
		mBtnStartService.setOnClickListener(this);
		mBtnStopService.setOnClickListener(this);
		mBtnBindService.setOnClickListener(this);
		mBtnUnBindService.setOnClickListener(this);

	}
	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.start_service:
			Intent mStartIntent=new Intent(this, MyService.class);
			startService(mStartIntent);

			break;

		case R.id.stop_service:
			Intent mStopIntent=new Intent(this, MyService.class);
			stopService(mStopIntent);
			break;
		case R.id.bind_service:
			Intent mBindIntent=new Intent(this, MyService.class);
			bindService(mBindIntent, connection, BIND_AUTO_CREATE);
			break;
		case R.id.unbind_service:
			unbindService(connection);
			break;

		default:
			break;
		}
	}

}

到此为止,我们已经写好了一个带有Service功能的程序。然后我们运行程序,点击Start Service按钮,然后点击Stop Service按钮,可以看到如下打印结果:

如果在不关闭Service的情况下,连续点击三次Start Sevice 按钮,程序将会连续三次启动Service,打印信息如下:

从上述两种不同的操作以及打印信息,我们验证了前面MyService注释部分注意的内容的正确性,如下:

onCreate()方法只会在Service第一次被创建的时候调用,如果当前Service已经被创建过了, 不管怎样调用startService方法,onCreate()方法都不会再执行。

现在我们已经了解了第一种方式,那么我接下来看看第二种方式:

在第一种方式中,MyService与MainActivity之间基本上不存在太多的关联,因此MyService与MainActivity之间无法进行通信、数据交换。如果想让MyService和MainActivity之间进行方法调用或数据交换,则应该采用第二种方式启动MyService,即使用bindService()和unbindService()方法启动、关闭Service。在使用第二种方式启动MyService之前,肯定是要修改前面MyService的代码的,修改之后的代码如下:

public class MyService extends Service{

	public static final String TAG=MyService.class.getSimpleName();
	private MyBinder mBinder=new MyBinder();
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.v(TAG, "onBind() executed");
		return mBinder;
	}
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.v(TAG, "onCreate() executed");
		Log.v(TAG, "MyService thread id is "+Thread.currentThread().getId());

	}
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.v(TAG, "onStartCommand() executed");
		return super.onStartCommand(intent, flags, startId);
	}
	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.v(TAG, "onDestroy() executed");
	}
	class MyBinder extends Binder
	{
		public void startDownload()
		{
			Log.v(TAG, "startDownload() executed");
		}
	}

}

在进行操作之前,我们先了解一下bindService方法:

Context的bindService()方法的源码如下:

 public boolean bindService(Intent service, ServiceConnection conn,
            int flags) {
        return mBase.bindService(service, conn, flags);
    }

这里解释一下该方法的三个参数:

service:该参数通过Intent指定要启动的Service。

conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情况。当访问者与Service之间连接成功时将回调该ServiceConnecttion对象的onServiceConnected(ComponentName name,IBinder service)方法;当Service所在的宿主进程由于异常终止或由于其他原因终止,导致该Service与访问者之间断开连接时回调该ServiceConnection对象的onServiceDisconnected(ComponentName
name)方法。

注意:当调用者主动通过unBindService()方法断开与Service的连接时,ServiceConnection对象的onServiceDisconnected(ComponentName name)方法并不会被调用。

flags:指定绑定时是否自动创建Service(如果Service还未创建)。该参数可指定为0(不自动创建)或BIND_AUTO_CREATE(自动创建)。

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

额,啰嗦了这么多,是不是有点晕了,咱们看看第二种方式启动MyService的执行效果吧,运行程序,点击Bind Service,然后点击unBind Service,打印信息如下:

通过上图我们可以看到,MainActivity已经成功的和MyService进行了通信。我们在MainActivity的成员对象connection的onServiceConnected的方法中调用了startDownload()方法。

下面我们来总结一下:

开发Service需要两个步骤:(1)定义一个继承Service的子类。(2)在AndroidManifest.xml文件中配置该Service。

启动Service有两种方式:(1)startService方法(2)bindService方法

通过startService方式启动Service,Service与访问者之间的基本上没有太大的关联。通过bindService方式启动Service,可以实现Service与访问者之间的通信。那么当通过bindService启动Service时,是如何进行通信的呢?我们按照本案例分析一下,当我们开发MyService类时,我们必须实现的方法是IBinder onBinder(Intent intent),当我们通过bindService方法启动MyService时,我们已经把MainActivity与MyService绑定在一起了,这时MyService方法的onBind方法所返回的IBinder对象将会传给MainActivity的成员connection里的onServiceConnected(ComponentName
name,IBinder service)方法的service参数,这样MainActivity就可通过该IBinder对象与MyService进行通信了。

细心的通信会发现,通过startService启动Service时,调用了onStartCommand方法,而通过bindService方法启动Service时,并没有调用onStartCommand方法,这是为什呢?这是因为两种方式启动Service,导致Service的生命周期略有不同。在下一篇的Service的生命周期中,我会讲述清楚。

好了,BB了这么多,我想对于Service的基础知识应该差不多了,我会在文章末尾提供该Demo的下载地址,如果对你有帮助可以稍微顶一下奥,如果文中有哪里不正确,欢迎指出,如果还有疑问之处,或者我没有阐述清楚的地方,请留言指出,谢谢。

转载请注明出处:http://blog.csdn.net/android_jiangjun/article/details/45458063

时间: 2024-10-06 01:15:02

Android 回顾Service之Service基础使用的相关文章

Android笔记之 Web Service 基础

一.Web Service是什么? 就是网络服务,根据W3C的定义,WebServices(Web服务)是一个用于支持网络间不同机器互操作的软件系统,它是一种自包含.自描述和模块化的应用程序,它可以在网络中被描述.发布和调用,可以将它看作是基于网络的.分布式的模块化组件.  Web Services是建立在通用协议的基础之上的,包括HTTP.SOAP.UDDI.WSDL等.其中Web Service三要素就是SOAP.WSDL和UDDI. SOAP用来描述传递信息的格式, WSDL用来描述如何访

Android开发6:Service的使用(简单音乐播放器的实现)

前言 啦啦啦~各位好久不见啦~博主最近比较忙,而且最近一次实验也是刚刚结束~ 好了不废话了,直接进入我们这次的内容~ 在这篇博文里我们将学习Service(服务)的相关知识,学会使用 Service 进行后台工作, 学会使用 Service 与 Activity 进行通信,并在此知识基础上学会使用 MediaPlayer和简单的多线程编程.使用 Handle 更新 UI,并设计成功一个简单的音乐播放器. 是不是很高大上呢~一起来学习~ 基础知识 Service作为Android四大组件之一,在每

Android Api Component---翻译Service

一个service是一个在后台执行长时间的操作并且不需要提供一个用户接口的应用程序组件.另一个应用程序能够开启service并且继续运行在后台甚至如果用户切换到另一个应用程序.此外,一个组件可以绑定到service与它交互而且甚至可以执行进程间通信(IPC).例如一个service也许操作网络事务,播放音乐,执行文件I/O或者跟一个内容提供交互,所有那些都是在后台执行的. 一个service本质上可以接受两种组成: Started 当应用程序通过调用startService()的时候,一个ser

Android四大组件之Service的介绍

Service的基本认识 Service是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.Service可由其他应用组件启动,而且即使用户切换到其他应用,Service仍将在后台继续运行.Service主要用于在后台处理一些耗时的逻辑,或者去执行某些需要长期运行的任务.必要的时候我们甚至可以在程序退出的情况下,让Service在后台继续保持运行状态. Service和Activity很相似,但是区别在于:Service一直在后台运行,没有用户界面,所以不会到前台,如果Service被

深入剖析Android四大组件(二)——Service服务之启动与绑定

如果说Activity通常都会提供一个用户界面UI的话,那么服务则不会提供任何用户界面,尽管如此,服务的作用仍然非常重要,它为我们提供了一种类似守护线程的手段来维持一些希望在退出以后仍然能持续运行的程序. 1.服务 既然服务的作用如此重要,本篇主要讲解如何使用服务和声明应用程序服务,下一节讲解怎么高效率的运用服务. ①何为服务 服务是一个应用程序组件,它在后台执行运行时间比较长的操作,不提供用户界面.它可以被其他应用程序组件启动或停止,并且当用户切换到另一个应用程序时,它仍然在后台持续的运行.另

Android四大基本组件-Service详解

一.官方文档 Class Overview A Service is an application component representing either an application's desire to perform a longer-running operation while not interacting with the user or to supply functionality for other applications to use. Each service c

Android自学之路——Service与Activity通信

A)MainActivity 类的代码 1 package com.example.cms.service; 2 3 import android.app.Service; 4 import android.content.ComponentName; 5 import android.content.Intent; 6 import android.content.ServiceConnection; 7 import android.os.IBinder; 8 import android.

Android 四大组件之Service

---恢复内容开始--- 1,Service的生命周期 onCreate第一次创建service的时候调用. onStartCommand启动service的时候调用. onStart(This method was deprecated in API level 5. Implement onStartCommand(Intent, int, int) instead.) onDestroy销毁的时候调用. 2,进程优先级(由高到低):(红色字体的两个进程是经常被系统回收的两个进程)    1

Android使用简单的Service

首先要自定义一个Service,设定它在后台要干什么. public class MyService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { //这部分就是在开启服务后要执行的东西,服务会在后台一直做这