Android服务类Service详细解析

Service有什么作用?

许多人不明白service是用来干嘛的,其实Service作为Android四大组件之一,可以理解为一个运行在后台的Activity,它适用于处理一些不干扰用户的长时间的后台操作,比如你播放器播放音乐之后跳到其它页面,音乐需要继续播放,那么这个时候就可以将音乐的播放一直运行在后台服务中,需要启动播放的时候就通过Activity去启动服务,再通过服务去调用播放,需要停止的时候就停止服务。

有人可能会问,Thread也可以实现后台运行,为什么不用Thread而使用Service呢?

Service和Thread是完全不同的两个概念,thread是子线程,是与主线程没有交集的,而Service是运行在主线程上的,是与主线程有交集。当然你会说为什么服务运行在主线程中不会反而影响性能吗为何还要用它?其实Service作为Android系统组件,是与Activity等立的,我们完全可以在其中定义子线程进行后台操作。如果需要大量的后台费时数据处理操作,最好的方式是在Service中开子线程,而不是直接开一个子线程,这样是为了提高子线程的优先级,而不会轻易被系统杀掉。

Thread是独立于主线程的,即使Activity结束了,假如你没有主动对它的子线程进行关闭,Thread仍有可能还在默默运行着,这个时候,你已经控制不到这些子线程了因为你已经把持有该Activity给结束掉了,这样对于程序很不安全。

举个例子:如果你的应用是一个聊天的应用,需要创建一个Thread每隔一小段时间就去访问服务器并实时显示有没有人发送了消息给你,那这个时候当你跳转到别的Activity比如个人设置等页面,而原来持有该Thread的Activity已经finfish,等你回去的时候已经控制不了你刚才在聊天Activity创建的那个子线程了,同样也就无法正常关闭这些子线程了。那么这个时候就需要service了,因为service是独立于Activity的,可以在其中创建子线程,即使Activity关闭了,也能够操作管理或者关闭这些子线程。而且不Service也不是和Activity一一对应,可以有多个Activity对应一个Service,这些Thread是无法做到的。

Service的使用方法:

原始方式创建服务:

定义一个类为MyService,继承自Service,并实现其中唯一的抽象方法:onbind(),其用处见下文:

public class MyService extends Service{
	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}
}

这样一个最原始的服务类就创建完成,接下来我们要在Activity中去启动它(通过intent启动):

Intent intent = new Intent(MainActivity.this,MyService.class);
startService(intent);

这个时候我跑一下程序,会发现程序崩溃了。报错:android:content:ActivityNotFoundException:Unable to find exnlicit activity class。问题就在于Service也是Android四大组件之一,必须要在AndroidMainfest.xml文件中注册这个服务:

注册完成之后再运行一遍,便成功启动服务。

如何停止服务:

Intent intent = new Intent(MainActivity.this,MyService.class);
stopService(intent);

绑定方式创建服务:

以上是通过startService方式启动服务,这种情况下除非主动关闭,不然即使Activity关闭了,服务依旧可以在后台一直运行

还有另外一种能够通过与Activity绑定的服务,这种情况下一旦Activity关闭了,服务也会相应关闭:

这时候就需要调用我们一开始说的onBind方法,binder在这个时候就相当于连接点:

在我们自定义的MyService类中,添加一个IBinder对象,并创建一个MyBinder内部类,在里面定义一个方法能够获得当前服务,并且重写onBind以及onUnBind方法:

public class MyService extends Service{

	private final IBinder binder = new MyBinder();  

	public class MyBinder extends Binder {
        	MyService getService() {
            		return MyService.this;
        	}
    	} 

	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d("MyService", "onBind...");
		return binder;
	}

	@Override
	public boolean onUnbind(Intent intent) {
		// TODO Auto-generated method stub
		Log.d("MyService", "onUnBind...");
		return super.onUnbind(intent);
	}
}

这种方式下启动服务需要通过调用onBind方法:

Intent intent = new Intent(MainActivity.this,MyService.class);
bindService(intent, connection, Context.BIND_AUTO_CREATE);//这里即绑定并启动了服务

可以看到有3个参数,第一个即传入启动该MyService的intent,第二个传入的是一个ServiceConnection对象,第三个是调用系统的变量表示自动绑定,其中,connection的创建如下:

final ServiceConnection connection = new ServiceConnection() {
	@Override
	public void onServiceDisconnected(ComponentName arg0) {
		// TODO Auto-generated method stub
		//onServiceDisconnected()方法在正常情况下是不被调用的,它的调用时机是当Service服务被异外销毁时		,例如内存的资源不足时
	}

	@Override
	public void onServiceConnected(ComponentName arg0, IBinder binder) {
		// TODO Auto-generated method stub
		MyBinder mybinder = (MyBinder)binder;
		MyService myservice = mybinder.getService();  //获得该服务
		//在这里获取有关服务的各种信息包括状态等等
	}
};

停止服务:通过调用onUnbind方法,传入刚才的connection,就会停止服务

上文我们用两种方式演示了如何创建一个初始的Service,但会有疑问:如何查看Service到底运行了没有?

public boolean isServiceWork(Context mContext, String serviceName) {
	boolean isWork = false;
	ActivityManager myAM = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
	List<RunningServiceInfo> myList = myAM.getRunningServices(40);
	if (myList.size() <= 0) {
		return false;
	}
	for (int i = 0; i < myList.size(); i++) {
		String mName = myList.get(i).service.getClassName().toString();
		if (mName.equals(serviceName)) {
			isWork = true;
			break;
		}
	}
	return isWork;
}  

调用这个方法,并传入当前Activity的context,以及服务名:包名+服务的类名(例如:com.example.MyService)

如果结果返回true则表示正在运行,false表示已经关闭。

Service的生命周期:

原始方式的生命周期:

我们可以通过重写Service中的onCreate、onStartCommand、onDestroy方法并分别打印日志来进行查看:

public class MyService extends Service{

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.d("MyService", "onCreate...");
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub
		Log.d("MyService", "onStartCommand...");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d("MyService", "onDestroy...");
	}

}

在布局文件中创建两个按钮:

代码调用:

startservice = (Button)this.findViewById(R.id.startservice);
stopservice = (Button)this.findViewById(R.id.stopservice);
startservice.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(MainActivity.this,MyService.class);
		startService(intent);
	}
});

stopservice.setOnClickListener(new OnClickListener() {

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		Intent intent = new Intent(MainActivity.this,MyService.class);
		stopService(intent);
	}
});

运行程序,点击启动服务按钮,查看logcat打印:

再点击多几次启动服务按钮:

点击关闭服务按钮:

可以看出,当我们第一次点击启动服务时,调用了服务的onCreate方法,当我们再点击多次启动时,只调用服务的onStartCommand方法,点击关闭的时候,调用了服务的onDestroy方法。所以我们大概了解了服务的生命周期:

1.第一次启动服务时,调用onCreate

2.第二次启动服务时,不会再调用onCreate而是调用onStartCommand

3.关闭服务时,调用onDestroy销毁

流程图如下:

绑定方式的生命周期:

代码上文已经讲述,这里不再描述,同理在onBind和onUnBind方法中打印日志,可得到其运行流程如下:

onCreate --> onBind(只一次,不可多次绑定) --> onUnbind --> onDestory

时间: 2024-10-07 12:42:32

Android服务类Service详细解析的相关文章

Android 服务类Service 的详细学习

上一篇说到了通知栏Notification,提起通知栏,不得让人想到Service以及BroadcastReceive,作为android的4大组建的2个重要成员,我们没少和它们打交道.它们可以在无形中使我们的软件和网络.数据库.系统等进行交互,之后通过UI(Notification就是一种展示方式)把结果展现在我们面前.可以说,他们是android生命体系里面的神经系统,通过反射条件让身体展现不同的状态.在整个系统中,广播接收器充当着是传输者和监听者的角色,它把系统的一点点变化都反馈上去,之后

Android 服务类Service 的具体学习

上一篇说到了通知栏Notification,提起通知栏,不得让人想到Service以及BroadcastReceive,作为android的4大组建的2个重要成员,我们没少和它们打交道.它们能够在无形中使我们的软件和网络.数据库.系统等进行交互,之后通过UI(Notification就是一种展示方式)把结果展如今我们面前.能够说,他们是android生命体系里面的神经系统,通过反射条件让身体展现不同的状态.在整个系统中,广播接收器充当着是传输者和监听者的角色,它把系统的一点点变化都反馈上去,之后

Android服务之Service

Android服务之Service android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你地理信息位置的改变,或者启动一个服务来运行并一直监听某种动作. Service和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的请求或者动作.你可以在服务中开一一个线程,在线程中做耗时动作. 那么究竟Service怎么使用呢? 老规矩,先来点基础知识. 一

Android基础(五) Service全解析----看不见的Activity

一.服务的介绍: 作为Android四大组件之中的一个,Service(服务)也常常运用于我们的日常使用中,它与Activity的差别在于:Service一直在后台执行.没实用户界面.所以绝不会到前台来.但Service被启动起来之后.它就和Activity一样.全然具有自己的生命周期. 在关于程序中是选择用Activity还是Service的一个选择标准就是:假设某个程序组件须要执行时向用户呈现某种用户界面.或者该程序须要与用户交互,就须要使用Activity,否则就该考虑使用Service.

Android服务之Service(其一)

转载地址:http://www.cnblogs.com/zhangdongzi/archive/2012/01/08/2316711.html android中服务是运行在后台的东西,级别与activity差不多.既然说service是运行在后台的服务,那么它就是不可见的,没有界面的东西.你可以启动一个服务Service来播放音乐,或者记录你地理信息位置的改变,或者启动一个服务来运行并一直监听某种动作. Service和其他组件一样,都是运行在主线程中,因此不能用它来做耗时的请求或者动作.你可以

android服务(service)初步——通话录音

启动服务之后,监听手机TelephonyManager状态,根据不同情况做出选择,源码以及截图如下: 生成的录音文件: Log日志: 这个不知道为什么,点击多次停止服务的时候,总是会出现下面的BUG: 图片看不清楚,我把日志复制了出来如下: 09-21 19:56:31.850: ERROR/audio_input(34): unsupported parameter: x-pvmf/media-input-node/cap-config-interface;valtype=key_specif

Android服务之Service(四)--ASDL传递复杂数据对象

此实例与前面aidl不同之处在于,传递的数据比较复杂,传递了自定义数据对象,本实例使用到了两个数据对象Person和Pet,其中Person是作为远程调用Service传递的参数,Pet是远程Service返回调用端的数据.像Java的RMI需要将数据对象序列化一样,此数据对象也需要序列化,因此android要求远程Service传递的参数和返回值需要实现Parcelable接口. 实例化Parcelable接口不仅需要实例化接口中的方法,而且要求在实现类中定义一个名为CREATOR,类型为Pa

android Application类的详细介绍

在代码中经常看到application这个类,一直不知道这个是干什么用的,今天刚好有点时间,所以进行了详细的学习. 一.先对它的整体概念解释: 在android源码中对他的描述是; * Base class for those who need to maintain global application state. You can        * provide your own implementation by specifying its name in your        *

Android服务之Service(三)关于AIDL进程间通信

转载:http://www.cnblogs.com/zhangdongzi/archive/2012/01/09/2317197.html 一.基础知识 AIDL的作用 在Android平台,每个应用程序App都运行在自己的进程空间.通常一 个进程不能访问另一个进程的内存空间(一个应用不能访问另一个应用),如果想沟通,需要将对象分解成操作系统可以理解的基本单元,Android提供了AIDL来处理. AIDL (Android Interface Definition Language) 是一种I