详解Android中Service服务的基础知识及编写方法

首先,让我们确认下什么是service?

service就是android系统中的服务,它有这么几个特点:它无法与用户直接进行交互、它必须由用户或者其他程序显式的启动、它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小哦。

那么,什么时候,我们需要使用service呢?
        我们知道,service是运行在后台的应用,对于用户来说失去了被关注的焦点。这就跟我们打开了音乐播放之后,便想去看看图片,这时候我们还不想音乐停止,这里就会用到service;又例如,我们打开了一个下载链接之后,我们肯定不想瞪着眼睛等他下载完再去做别的事情,对吧?这时候如果我们想手机一边在后台下载,一边可以让我去看看新闻啥的,就要用到service。

service分类:
       一般我们认为service分为两类,本地service和远程service。

1. 本地service:顾名思义,那就是和当前应用在同一个进程中的service,彼此之间拥有共同的内存区域,所以对于某些数据的共享特别的方便和简单;

2. 远程service:主要牵扯到不同进程间的service访问。因为android的系统安全的原因导致了我们在不同的进程间无法使用一般的方式共享数据。在这里android为我们提供了一个AIDL工具。(android interface description language)android接口描述语言。在后边我们将会对其进行详细的介绍。

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生命周期:

和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);

/**
  * 链接到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进行简单的应用
 */
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>

最终效果图:

(0)

相关推荐

  • Android中实现开机自动启动服务(service)实例

    最近在将 HevSocks5Client 移植到 Android 上了,在经过增加 signalfd 和 timerfd 相关的系统调用支持后,就可以直接使用 NDK 编译出 executable 了.直接的 native exectuable 在 Android 系统总还是不太方便用哦.还是做成一个 apk 吧,暂定只写一个 service 并开机自动启用,无 activity 的. Java 中调用 native 程序我选择使用 JNI 方式,直接在 JNI_OnLoad 方法中调用 pth

  • android开发教程之开机启动服务service示例

    个例子实现的功能是:1,安装程序后看的一个Activity程序界面,里面有个按钮,点击按钮就会启动一个Service服务,此时在设置程序管理里面会看的有个Activity和一个Service服务运行2,如果手机关机重启,会触发你的程序里面的Service服务,当然,手机启动后是看不到你的程序界面.好比手机里面自带的闹钟功能,手机重启看不到闹钟设置界面只是启动服务,时间到了,闹钟就好响铃提醒. 程序代码是: 首先要有一个用于开机启动的Activity,给你们的按钮设置OnClickListener

  • 在Android中 获取正在运行的Service 实例

    public class ServiceList extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tv = new TextView(this); ActivityManager activityManger = (ActivityManager) getSystemService(ACTIV

  • android中soap协议使用(ksoap调用webservice)

    如下面代码所示: 复制代码 代码如下: SoapObject request  = new SoapObject(serviceNamespace, methodName); SoapObject构造函数的两个参数含义为: serviceNamespace – 你的webservice的命名空间,既可以是 http://localhost:8088/flickrBuddy/services/Buddycast这样的,也可以是 urn:PI/DevCentral/SoapService这样的: m

  • 解析Android中如何做到Service被关闭后又自动启动的实现方法

    首先要说的是,用户可能把这种做法视为流氓软件.大部分时候,程序员也不想把软件做成流氓软件,没办法,领导说了算. 我们在使用某些Android应用的时候,可能会发现安装了某应用以后,会有一些服务也会随之运行.而且,这些服务每次都会随着手机开机而启动.有的服务做的更绝,当用户在运行的服务中手动停止该服务以后,过了一段时间,服务又自动运行了.虽然,从用户的角度来说,这种方式比较流氓.但是,从程序员的角度来说,这是如何做到的呢?经过研究,我发现有一种方式是可以实现的.下面就和大家分享. 先简单介绍,一会

  • Android中Service服务详解(一)

    本文详细分析了Android中Service服务.分享给大家供大家参考,具体如下: 一.Service简介 Service是Android中实现程序后台运行的解决方案,适用于去执行那些不需要和用户交互而且还要求长期运行的任务.Service是android 系统中的四大组件之一(Activity.Service.BroadcastReceiver.ContentProvider),它跟Activity的级别差不多,但不能自己运行只能后台运行,并且可以和其他组件进行交互. Service并不是运行

  • Android Service 服务不被杀死的妙招

    Service是android 系统中的一种组件,它跟Activity的级别差不多,但是他不能自己运行,只能后台运行,并且可以和其他组件进行交互. Android开发的过程中,每次调用startService(Intent)的时候,都会调用该Service对象的onStartCommand(Intent,int,int)方法,然后在onStartCommand方法中做一些处理. 从Android官方文档中,我们知道onStartCommand有4种int返回值,首先简单地讲讲int返回值的作用.

  • Android Service服务不被停止详解及实现

    Android Service服务一直运行: 最近有个项目需求是后台一直运行Service,但是一般都是可以手动停止的,这里就提供一个方法让Android Service服务一直运行,大家看下. 1.设置->应用->运行中->停止->杀死service 这样可以在service的onDestroy()方法中重启service public void onDestroy() { Intent service = new Intent(this, MyService.class); s

  • Android中的Service相关全面总结

    1.Service的种类 按运行地点分类: 类别 区别  优点 缺点   应用 本地服务(Local) 该服务依附在主进程上,  服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外Local服务因为是在同一进程因此不需要IPC,也不需要AIDL.相应bindService会方便很多.  主进程被Kill后,服务便会终止.  非常常见的应用如:HTC的音乐播放服务,天天动听音乐播放服务. 远程服务(Remote) 该服务是独立的进程,  服务为独立的进程,对应进程名格式为所在包名

  • Android中使用IntentService创建后台服务实例

    IntentService提供了在单个后台线程运行操作的简单结构.这允许它操作耗时操作,而不影响UI响应.同样,IntentService也不影响UI生命周期事件,所以,它在某些可能关闭AsyncTask的情况下,仍会继续运行(实测在Activity的onDestory里写AsyncTask无法运行). IntentService有如下限制: 1.它不能直接影响UI.要把结果反映给UI,需要发给Activity 2.工作请求会顺序运行.如果一个操作未结束,后面发送的操作必须等它结束(单线程) 3

  • Android中Service服务详解(二)

    本文详细分析了Android中Service服务.分享给大家供大家参考,具体如下: 在前面文章<Android中Service服务详解(一)>中,我们介绍了服务的启动和停止,是调用Context的startService和stopService方法.还有另外一种启动方式和停止方式,即绑定服务和解绑服务,这种方式使服务与启动服务的活动之间的关系更为紧密,可以在活动中告诉服务去做什么事情. 为了说明这种情况,做如下工作: 1.修改Service服务类MyService package com.ex

随机推荐