Android开发之Service服务详解

服务,作为Android四大组件之一,必然是重点。我们今天就来讲解一下有关服务的生命周期、两种开启方式以及相关用法。

服务有两种开启方式,一种是正常开启, 一种是以绑定的方式开启,当然,这两种方式可以组成混合开启。

一、服务的正常开启

正常开启服务的方法非常简单,我们先看如何定义一个服务

1、编写一个类,继承Service类。

我们先不管代码中的binder类。那个后续讲解用。

public class TestService extends Service {

	@Override
	public IBinder onBind(Intent arg0) {
		System.out.println("onBind");
		return new Mybinder();
	}

	@Override
	public void onCreate() {
		System.out.println("create");
		super.onCreate();
	}

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

	@Override
	@Deprecated
	public void onStart(Intent intent, int startId) {
		System.out.println("start");
		super.onStart(intent, startId);
	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		System.out.println("onStartCommand");
		return super.onStartCommand(intent, flags, startId);
	}

	@Override
	public boolean onUnbind(Intent intent) {
		System.out.println("onUnbind");
		return super.onUnbind(intent);
	}

	class Mybinder extends Binder implements IService {

		public void method() {

			System.out.println("serviceMethod");
		}

	}

}

2、清单文件中注册服务

  <service android:name="com.example.servicedemo.TestService" >
        </service>

3、正常开启服务

intent = new Intent(getBaseContext(), TestService.class);
		startService(intent);

4、正常关闭服务

	stopService(intent);

这里我们值得注意的是,一般服务的意图对象会做成全局变量,便于在退出的时候销毁服务。这是服务正常使用的步骤。正常使用的时候,服务的生命周期是这样的:

开启:
onCreate-->onStartCommand-->onStart

结束:
onDestory

正常情况下,服务只开启一次,既只执行一次onCreate方法,如果已经开启服务,再次执行startService方法时候,会跳过onCreate,直接执行onStartCommand方法以及之后的方法。其中onStart方法已经废弃

二、服务的绑定开启

有时候,我们需要调用服务里的方法,这个时候,我们就需要采取绑定的方式,开启服务了。关于绑定开启服务的原理,这个涉及的android的binder机制,这个我们在下一篇专题中在讲解。这里直接跳过。

采用绑定的方式开启服务,我们需要准备几个东西。

1、实现一个继承binder的类

2、activity里面实现一个实现ServiceConnection接口的类。

1、binder类的实现

绑定服务,会调用onBind的方法,然后返回一个IBinder的代理。所以我们需要实现一个继承Binder的类。然后在里面写一个方法,就可以调用服务里的方法了。其中IService是一个接口类,便于后续操作远程调用服务方法就这样一起写了。

class Mybinder extends Binder implements IService {

		public void method() {

			System.out.println("serviceMethod");
		}

	}

在onBind方法里返回这个binder

	@Override
	public IBinder onBind(Intent arg0) {
		System.out.println("onBind");
		return new Mybinder();
	}

2、拿到代理binder

因为Binder实现了IService接口,所以我们拿到的也是一个实现过IService的类。

	class Mycon implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName arg0, IBinder binder) {
			Iservice = (IService) binder;
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {

		}

	}

3、服务的绑定与调用服务方法和解绑

intent = new Intent(getBaseContext(), TestService.class);
		conn = new Mycon();
		bindService(intent, conn, BIND_AUTO_CREATE);

当这样绑定服务后,服务的生命周期执行是这样的:onCreate-->onBind,不会执行onStartCommand方法,拿到代理类后,我们可以执行服务里的方法了。

	findViewById(R.id.test).setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				//startService(intent);
				Iservice.method();
			}
		});

这样,就调用了服务里的方法。

采用绑定的方式开启服务有一个风险,就是如果采用绑定的方法开启服务,那么当你最小化程序的时候,会报错。程序会提醒你要解绑服务才能这样。这个时候我们就需要在一些actvity的生命周期里面解绑服务

unbindService(conn);

执行这行代码,就可以解绑服务了。执行的生命周期函是:onUnBind-->onDestory

三、服务的混合开启

之前,我们说,采用绑定的方式开启服务,就会造成最小化的时候程序报错,那么有什么办法解决呢?这个时候,我们就需要采用混合开启的方法开启服务了。

所谓的混合开启,就是在正常开启服务之后,在采用绑定的方法绑定服务。我们来看代码

intent = new Intent(getBaseContext(), TestService.class);
		startService(intent);
		conn = new Mycon();
		bindService(intent, conn, BIND_AUTO_CREATE);

这样就达到了混合开启服务的效果。他所执行的生命周期的函数为:onCreate-->onStartCommand-->onStart-->onBind

那么退出的时候,我们需要先解绑,在停止服务

				unbindService(conn);
				stopService(intent);
				conn=null;
				intent=null;

这个时候执行的生命周期函数为:onUnbind-->onDestory

四、调用远程服务的方法

有时候,我们需要调用别的应用里面的服务的方法,这个其实就是android的IPC机制原理的实现。我们今天就先讲讲实现步骤的方法代码。

1、将接口文件重命名为.aidl文件

package com.example.servicedemo;

interface IService {

	 void method();

}

我们将之前的IService接口文件的后缀名改为.aidl后,需要将里面的public等修饰字段去掉。

2、在新的应用中,新建一个与之前存放.aidl文件包名一样的包。

新建好之后,将.aidl文件复制到包里

3、修改之前服务类里的binder实现方法

	class Mybinder extends IService.Stub {

		public void method() {

			System.out.println("serviceDemomethod");
		}

	}

将之前的接口文件修改之后,我们直接继承接口文件自动生成的.Stub类即可

4、定义服务的隐试意图开启方式,并采用隐式意图开启服务

因为不能拿到别的应用里的服务的类名,所以我们需要采用隐式意图去开启服务并绑定。

        <service android:name="com.example.servicedemo.TestService" >
            <intent-filter>
                <action android:name="com.example.servicedemo.TestService.action" />
            </intent-filter>
        </service>

在绑定服务之前,需要重写一下代理接口实现类,这里不再采用强制转换了。

	class Mycon implements ServiceConnection {

		@Override
		public void onServiceConnected(ComponentName arg0, IBinder binder) {
			Iservice = IService.Stub.asInterface(binder);
		}

		@Override
		public void onServiceDisconnected(ComponentName arg0) {

		}

	}

然后绑定服务,就可以调用远程服务的方法了

<span style="white-space:pre">		</span>Intent intent = new Intent();
		intent.setAction("com.example.servicedemo.TestService.action");
		bindService(intent, new Mycon(), BIND_AUTO_CREATE);
		findViewById(R.id.test).setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				try {
					Iservice.method();
				} catch (RemoteException e) {
					e.printStackTrace();
				}

			}
		});

在服务使用的过程中,需要注意的是,结束服务的时候,一定要记得释放掉服务里的所有资源,尤其是服务里有开启子线程并无线循环的。

好了,服务的基本使用方法到此讲解结束,希望此文能帮助到大家。

时间: 2024-10-14 00:57:40

Android开发之Service服务详解的相关文章

Android开发之Html类详解

在进行Android开发中经常回忽略Html类.这个类其实很简单,就是将HTML标签文本解析成普通的样式文本.下面就让我么看一下这个类的具体介绍. 类结构: java.lang.Object    ? android.text.Html 类概述: 这个类用于处理的HTML字符串并将其转换成可显示的样式文本.但并不是所有的HTML标记的支持. 公有方法: 说其简单是应为它就有四个方法: Public Methods static String escapeHtml(CharSequence tex

Android开发之SQLite数据库详解

Android开发之SQLite数据库详解 请尊重他人的劳动成果,转载请注明出处:Android开发之SQLite数据库详解 http://blog.csdn.net/fengyuzhengfan/article/details/40194393 Android系统集成了一个轻量级的数据库:SQLite, SQLite并不想成为像Oracle.MySQL那样的专业数据库.SQLite只是一个嵌入式的数据库引擎,专门适用于资源有限的设备上(如手机.PDA等)适量数据存取. 虽然SQLite支持绝大

Android开发之SoundPool使用详解

使用SoundPool播放音效 如果应用程序经常播放密集.急促而又短暂的音效(如游戏音效)那么使用MediaPlayer显得有些不太适合了.因为MediaPlayer存在如下缺点: 1)         延时时间较长,且资源占用率高. 2)         不支持多个音频同时播放. Android中除了MediaPlayer播放音频之外还提供了SoundPool来播放音效,SoundPool使用音效池的概念来管理多个短促的音效,例如它可以开始就加载20个音效,以后在程序中按音效的ID进行播放.

Android开发之MediaRecorder类详解

MediaRecorder类详解 手机一般都有麦克风和摄像头,而Android系统就可以利用这些硬件来录制音视频了. 为了增加对录制音视频的支持,Android系统提供了一个MediaRecorder的类.该类的使用也非常简单,下面让我们来了解一下这个类: 一.类结构: java.lang.Object    ? android.media.MediaRecorder 二.类概述: 用于录制音频和视频的一个类. 三.状态图: 说明: 与MediaPlayer类非常相似MediaRecorder也

Android开发之EditText属性详解

1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: 把该EditText设为:android:password="true" // 以"."形式显示文本 (2)在代码里设置: 通过设置EditText的setTransformationMethod()方法来实现隐藏密码或这显示密码. editText.setTransformationMethod(PasswordTransformationMethod.getInstance());//设

【转】 Android开发之EditText属性详解

原文网址:http://blog.csdn.net/qq435757399/article/details/7947862 1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: 把该EditText设为:android:password="true" // 以”.”形式显示文本 (2)在代码里设置: 通过设置EditText的setTransformationMethod()方法来实现隐藏密码或这显示密码. editText.setTransformationMe

android开发之onCreate( )方法详解

onCreate( )方法是android应用程序中最常见的方法之一,那么,我们在使用onCreate()方法的时候应该注意哪些问题呢? 先看看Google Android Developers官网上的解释: onCreate(Bundle) is where you initialize your activity. Most importantly, here you will usually call setContentView(int) with a layout resource d

android开发之PreferenceScreen使用详解

是在惭愧,学习android也有一段时间了,今天才是第一次接触PreferenceScreen.记录下来,与大家分享. 本文参考:http://lovezhou.iteye.com/blog/1020361 PreferenceScreen使用步骤: 1.先在res文件夹中新建一个xml文件夹,用来存放preferences.xml文件 preferences.xml <?xml version="1.0" encoding="utf-8"?> <

android开发之Parcelable使用详解

想要在两个activity之间传递对象,那么这个对象必须序列化,android中序列化一个对象有两种方式,一种是实现Serializable接口,这个非常简单,只需要声明一下就可以了,不痛不痒.但是android中还有一种特有的序列化方法,那就是实现Parcelable接口,使用这种方式来序列化的效率要高于实现Serializable接口.不过Serializable接口实在是太方便了,因此在某些情况下实现这个接口还是非常不错的选择. 使用Parcelable步骤: 1.实现Parcelable