首先,让我们确认下什么是service?
service就是android系统中的服务,它有这么几个特点:它无法与用户直接进行交互、它必须由用户或者其他程序显式的启动、它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小哦。
那么,什么时候,我们需要使用service呢?
我们知道,service是运行在后台的应用,对于用户来说失去了被关注的焦点。这就跟我们打开了音乐播放之后,便想去看看图片,这时候我们还不想音乐停止,这里就会用到service;又例如,我们打开了一个下载链接之后,我们肯定不想瞪着眼睛等他下载完再去做别的事情,对吧?这时候如果我们想手机一边在后台下载,一边可以让我去看看新闻啥的,就要用到service。
service分类:
一般我们认为service分为两类,本地service和远程service。
本地service顾名思义,那就是和当前应用在同一个进程中的service,彼此之间拥有共同的内存区域,所以对于某些数据的共享特别的方便和简单;
远程service:主要牵扯到不同进程间的service访问。因为android的系统安全的原因导致了我们在不同的进程间无法使用一般的方式共享数据。在这里android为我们提供了一个AIDL工具。(android interface description language)android接口描述语言。在后边我们将会对其进行详细的介绍。
service生命周期:
和Activity相比,service的生命周期已经简单的不能再简单了,只有onCreate()->onStart()->onDestroy()三个方法。
Activity中和service有关的方法:
startService(Intent intent):启动一个service
stopService(Intent intent) :停止一个service
如果我们想使用service中的一些数据或者访问其中的一些方法,那么我们就要通过下面的方法:
public boolean bindService(Intent intent, ServiceConnection conn, int flags) ;
public void unbindService(ServiceConnection conn);
intent是跳转到service的intent,如 Intent intent = new Intent(); intent.setClass(this,MyService.class);
conn则是一个代表与service连接状态的类,当我们连接service成功或失败时,会主动触发其内部的onServiceConnected或onServiceDisconnected方法。如果我们想要访问service中的数据,可以在onServiceConnected()方法中进行实现,例如
- /**
- * 链接到service时触发。
- * name 链接到service组件的名称
- * service 在service中调用onBund时返回的IBinder,主要用来进行信息的交流
- */
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.i("通知", "链接成功!");
- MyBinder binder = (MyBinder)service;
- MyService myService = binder.getMyService();
- int count = myService.getCount();
- Log.i("通知", "count="+count);
- }
-------------------------------------------------------------------
使用service的步骤:
第一步:我们要继承service类,实现自己的service。
如果想要访问service中的某些值,我们通常会提供一个继承了Binder的内部类,通过onBund()方法返回给service请求。这里实际上巧妙的利用了内部类能够访问外部类属性的特点。
第二步:在androidManifest.xml中进行注册,如:
<!--
service配置开始
-->
<service android:name="MyService"></service>
<!--
service配置结束
-->
第三步:在activity中进行启动、绑定、解绑或者停止service。
(很多书上说,service与用户是不能交互的,其实这话很不正确,我们完全可以通过activity与service进行交互嘛!我觉得,确切的说法应该是service与用户不能进行直接的交互)。
------------------------------------------------------
下边提供一个调用service听音乐的例子:
activity代码:
- package cn.com.chenzheng_java;
- import cn.com.chenzheng_java.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.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- /**
- * @description 对service进行简单的应用
- * @author chenzheng_java
- * @since 2011/03/18
- *
- */
- public class ServiceActivity extends Activity implements OnClickListener{
- private Button button_start ;
- private Button button_bind ;
- private Button button_destroy ;
- private Button button_unbind;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.service);
- button_start = (Button) findViewById(R.id.button1_service);
- button_bind = (Button) findViewById(R.id.button2_service);
- button_destroy = (Button) findViewById(R.id.button3_service);
- button_unbind = (Button) findViewById(R.id.button4_service);
- button_start.setOnClickListener(this);
- button_bind.setOnClickListener(this);
- button_destroy.setOnClickListener(this);
- button_unbind.setOnClickListener(this);
- }
- private class MyServiceConnection implements ServiceConnection{
- /**
- * 链接到service时触发。
- * name 链接到service组件的名称
- * service 在service中调用onBund时返回的IBinder,主要用来进行信息的交流
- */
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- Log.i("通知", "链接成功!");
- MyBinder binder = (MyBinder)service;
- MyService myService = binder.getMyService();
- int count = myService.getCount();
- Log.i("通知", "count="+count);
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- Log.i("通知", "链接未成功!");
- }
- }
- private MyServiceConnection serviceConnection = new MyServiceConnection();
- @Override
- public void onClick(View v) {
- if(v == button_start){
- Intent intent = new Intent();
- intent.setClass(getApplicationContext(), MyService.class);
- startService(intent);
- }
- if(v == button_bind){
- Intent intent = new Intent();
- intent.setClass(getApplicationContext(), MyService.class);
- bindService(intent,serviceConnection , BIND_AUTO_CREATE);
- }
- if(v==button_destroy){
- Intent intent = new Intent();
- intent.setClass(getApplicationContext(), MyService.class);
- stopService(intent);
- }
- if(v==button_unbind){
- unbindService(serviceConnection);
- }
- }
- }
继承service的类:
- package cn.com.chenzheng_java;
- import android.app.Service;
- import android.content.Intent;
- import android.media.MediaPlayer;
- import android.os.Binder;
- import android.os.IBinder;
- import android.util.Log;
- /**
- * @description 实现自己的service
- * @author chenzheng_java
- * @since 2011/03/18
- */
- public class MyService extends Service {
- MediaPlayer mediaPlayer;
- /**
- * 当用户调用bindService方法时会触发该方法 返回一个IBinder对象,我们可以通过该对象,对service中 的某些数据进行访问
- */
- @Override
- public IBinder onBind(Intent intent) {
- Log.i("通知", "service绑定成功!");
- return new MyBinder();
- }
- @Override
- public void onCreate() {
- Log.i("通知", "service创建成功!");
- mediaPlayer = MediaPlayer.create(this, R.raw.aiweier);
- mediaPlayer.setLooping(false);
- super.onCreate();
- }
- @Override
- public void onDestroy() {
- mediaPlayer.stop();
- Log.i("通知", "service销毁成功!");
- super.onDestroy();
- }
- @Override
- public void onRebind(Intent intent) {
- Log.i("通知", "service重新绑定成功!");
- super.onRebind(intent);
- }
- @Override
- public void onStart(Intent intent, int startId) {
- mediaPlayer.start();
- Log.i("通知", "service start成功!");
- super.onStart(intent, startId);
- }
- @Override
- public boolean onUnbind(Intent intent) {
- mediaPlayer.stop();
- Log.i("通知", "service解绑成功!");
- return super.onUnbind(intent);
- }
- private int count = 100;
- public int getCount() {
- return count;
- }
- public void setCount(int count) {
- this.count = count;
- }
- public class MyBinder extends Binder {
- /**
- * @return 返回一个个人的service对象
- */
- MyService getMyService() {
- return MyService.this;
- }
- }
- }
service.xml代码:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent">
- <Button android:text="启动" android:id="@+id/button1_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
- <Button android:text="绑定" android:id="@+id/button2_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
- <Button android:text="销毁" android:id="@+id/button3_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
- <Button android:text="解绑" android:id="@+id/button4_service" android:layout_width="wrap_content" android:layout_height="wrap_content"></Button>
- </LinearLayout>
androidManifest.xml
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="cn.com.chenzheng_java"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="8" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name="ServiceActivity"
- android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <!--
- service配置开始
- -->
- <service android:name="MyService"></service>
- <!--
- service配置结束
- -->
- </application>
- </manifest>
最终效果图:
---------------------------------------------------------------------