详解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>

最终效果图:

时间: 2024-11-10 11:37:55

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

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

首先,让我们确认下什么是service?         service就是android系统中的服务,它有这么几个特点:它无法与用户直接进行交互.它必须由用户或者其他程序显式的启动.它的优先级比较高,它比处于前台的应用优先级低,但是比后台的其他应用优先级高,这就决定了当系统因为缺少内存而销毁某些没被利用的资源时,它被销毁的概率很小哦. 那么,什么时候,我们需要使用service呢?        我们知道,service是运行在后台的应用,对于用户来说失去了被关注的焦点.这就跟我们打开了音乐播

详解Android中App的启动界面Splash的编写方法_Android

一.Splash界面的作用用来展现产品的Logo 应用程序初始化的操作 检查应用程序的版本 检查当前应用程序是否合法注册 二.界面的xml定义写一个布局背景设置为产品的logo图片,再添加一个textview显示版本号. <TextView android:id="@+id/tv_splash_version" android:layout_width="wrap_content" android:layout_height="wrap_conten

详解Android中实现ListView左右滑动删除条目的方法_Android

使用Scroller实现绚丽的ListView左右滑动删除Item效果这里来给大家带来使用Scroller的小例子,同时也能用来帮助初步解除的读者更加熟悉的掌握Scroller的使用,掌握好了Scroller的使用我们就能实现很多滑动的效果.例如侧滑菜单,launcher,ListView的下拉刷新等等效果,我今天实现的是ListView的item的左右滑动删除item的效果,现在很多朋友看到这个效果应该是在Android的通知栏下拉中看到这个滑动删除的效果吧,我看到这个效果是在我之前的三星手机

详解Android中实现ListView左右滑动删除条目的方法

使用Scroller实现绚丽的ListView左右滑动删除Item效果 这里来给大家带来使用Scroller的小例子,同时也能用来帮助初步解除的读者更加熟悉的掌握Scroller的使用,掌握好了Scroller的使用我们就能实现很多滑动的效果.例如侧滑菜单,launcher,ListView的下拉刷新等等效果,我今天实现的是ListView的item的左右滑动删除item的效果,现在很多朋友看到这个效果应该是在Android的通知栏下拉中看到这个滑动删除的效果吧,我看到这个效果是在我之前的三星手

详解Android中的Service

Service简介: Service是被设计用来在后台执行一些需要长时间运行的操作. Android由于允许Service在后台运行,甚至在结束Activity后,因此相对来说,Service相比Activity拥有更高的优先级. 创建Service: 要创建一个最基本的Service,需要完成以下工作:1)创建一个Java类,并让其继承Service 2)重写onCreate()和onBind()方法 其中,onCreate()方法是当该Service被创建时执行的方法,onBind()是该S

详解Android中Handler的内部实现原理_Android

本文主要是对Handler和消息循环的实现原理进行源码分析,如果不熟悉Handler可以参见博文<详解Android中Handler的使用方法>,里面对Android为何以引入Handler机制以及如何使用Handler做了讲解. 概括来说,Handler是Android中引入的一种让开发者参与处理线程中消息循环的机制.我们在使用Handler的时候与Message打交道最多,Message是Hanlder机制向开发人员暴露出来的相关类,可以通过Message类完成大部分操作Handler的功

详解Android中Intent对象与Intent Filter过滤匹配过程_Android

如果对Intent不是特别了解,可以参见博文<详解Android中Intent的使用方法>,该文对本文要使用的action.category以及data都进行了详细介绍.如果想了解在开发中常见Intent的使用,可以参见<Android中Intent习惯用法>. 本文内容有点长,希望大家可以耐心读完. 本文在描述组件在manifest中注册的Intent Filter过滤器时,统一用intent-filter表示. 一.概述 我们知道,Intent是分两种的:显式Intent和隐式

详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题

详解 Android中Libgdx使用ShapeRenderer自定义Actor解决无法接收到Touch事件的问题 今天在项目中实现了一个效果,主要是画一个圆.为了后续使用方便,将这个圆封装在一个自定义Actor(CircleActot)中,后续想显示一个圆的时候,只要创建一个CircleActor中即可. 部分代码如下所示: package com.ef.smallstar.unitmap.widget; import android.content.res.Resources; import

详解Android中图片的三级缓存及实例

详解Android中图片的三级缓存及实例 为什么要使用三级缓存 如今的 Android App 经常会需要网络交互,通过网络获取图片是再正常不过的事了 假如每次启动的时候都从网络拉取图片的话,势必会消耗很多流量.在当前的状况下,对于非wifi用户来说,流量还是很贵的,一个很耗流量的应用,其用户数量级肯定要受到影响 特别是,当我们想要重复浏览一些图片时,如果每一次浏览都需要通过网络获取,流量的浪费可想而知 所以提出三级缓存策略,通过网络.本地.内存三级缓存图片,来减少不必要的网络交互,避免浪费流量