Android Service 详解

来源:互联网 发布:sql 格式化 java代码 编辑:程序博客网 时间:2024/05/21 09:13


Service概念及用途

Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,那 我们什么时候会用到Service呢?比如我们播放音乐的时候,有可能想边听音乐边干些其他事情,当我们退出播放音乐的应用,如果不用Service,我 们就听不到歌了,所以这时候就得用到Service了。


Service的两种模式
本地服务 Local Service 用于应用程序内部。
  它可以启动并运行,直至有人停止了它或它自己停止。在这种方式下,它以调用Context.startService()启动,而以调用Context.stopService()结束。它可以调用Service.stopSelf() 或 Service.stopSelfResult()来自己停止。不论调用了多少次startService()方法,你只需要调用一次stopService()来停止服务。
  用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
远程服务 Remote Service 用于android系统内部的应用程序之间。
  它可以通过自己定义并暴露出来的接口进行程序操作。客户端建立一个到服务对象的连接,并通过那个连接来调用服务。连接以调用Context.bindService()方法建立,以调用 Context.unbindService()关闭。多个客户端可以绑定至同一个服务。如果服务此时还没有加载,bindService()会先加载它。
  可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。


Servicie的生命周期

Service的生命周期并不像Activity那么复杂,它只继承了onCreate(),onStart(),onDestroy()三个方法,当我们第一次启动Service时,先后调用了onCreate(),onStart()这两个方法,当停止Service时,则执行onDestroy()方法,这里需要注意的是,如果Service已经启动了,当我们再次启动Service时,不会在执行onCreate()方法,而是直接执行onStart()方法。





服务只会开启一次, oncreate只会在服务创建的时候 执行 ,多次调用startService()方法,不会重复开启服务。多次调用stopService的方法 ,服务只会被停止一次,多次调用不会报错。多次调用bindService方法时,如果服务已经开启了 就不会再去执行oncreate(),如果服务是采用bind的方式 绑定的只能解绑一次。
如果服务被绑定过,就不能通过stopService的方法 停止服务了,要想停止服务 必须先手动的把服务解除绑定.然后才能停止服务:
startService - bindService - unbindservice - stopService(ondestroy);


startService - bindService - stopService(服务停不掉,因为被绑定了)- unbindservice(由于服务已经解除绑定,所以服务就离开的停止了).


如果我们想让服务在后台长期运行又想调用服务里面的方法,执行下列步骤即可:
startService - bindService - unbindservice - stopService(ondestroy);


具体可以参考官方docs:http://developer.android.com/guide/components/services.html


下面通过一个实例来演示Service的生命周期


main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical" >    <Button        android:id="@+id/bt_start"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="start服务" />    <Button        android:id="@+id/bt_bind"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="bind服务" />    <Button        android:id="@+id/bt_stop"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="stop服务" />    <Button        android:id="@+id/bt_unbind"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="unbind服务" />    <Button        android:id="@+id/bt_call"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="调用服务里面的方法" /></LinearLayout>


MyService.java

package cn.itcast.testservice;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.widget.Toast;public class MyService extends Service {@Overridepublic IBinder onBind(Intent intent) {System.out.println("onBind");return new MyBinder();}public class MyBinder extends Binder implements IService{@Overridepublic void callMethodInService() {methodInService();}}/** * 服务里面的一个方法. */public void methodInService(){Toast.makeText(this, "我是服务里面的方法", 0).show();}/** * 服务第一次被创建  调用的方法 */@Overridepublic void onCreate() {System.out.println("onCreate");super.onCreate();}@Overridepublic void onStart(Intent intent, int startId) {System.out.println("onStart");super.onStart(intent, startId);}/** * 服务在停止的时候 调用的方法 */@Overridepublic void onDestroy() {System.out.println("onDestroy");super.onDestroy();}}


DemoActivity.java

package cn.itcast.testservice;import android.app.Activity;import android.content.ComponentName;import android.content.Context;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class DemoActivity extends Activity implements OnClickListener {private Intent intent;private MyConn conn;private IService iService;@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);intent = new Intent(this, MyService.class);findView();}private void findView() {Button bt_start = (Button) findViewById(R.id.bt_start);Button bt_bind = (Button) findViewById(R.id.bt_bind);Button bt_stop = (Button) findViewById(R.id.bt_stop);Button bt_unbind = (Button) findViewById(R.id.bt_unbind);Button bt_call = (Button) findViewById(R.id.bt_call);bt_start.setOnClickListener(this);bt_bind.setOnClickListener(this);bt_stop.setOnClickListener(this);bt_unbind.setOnClickListener(this);bt_call.setOnClickListener(this);}@Overridepublic void onClick(View v) {switch (v.getId()) {case R.id.bt_start: // start的方式开启服务startService(intent);break;case R.id.bt_bind:// bind的方式开启服务conn = new MyConn();bindService(intent, conn, Context.BIND_AUTO_CREATE);break;case R.id.bt_stop: // stop的方式停止服务stopService(intent);break;case R.id.bt_unbind:// unbind的方式解除绑定服务try {unbindService(conn);} catch (Exception e) {e.printStackTrace();}break;case R.id.bt_call:// mybinder.callMethodInService();iService.callMethodInService();break;default:break;}}private class MyConn implements ServiceConnection {/** * onServiceConnected 当服务被成功绑定的时候 调用的方法 */@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {iService = (IService) service;}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}}@Overrideprotected void onDestroy() {super.onDestroy();try {unbindService(conn);} catch (Exception e) {e.printStackTrace();}}}


IService.java

package cn.itcast.testservice;public interface IService {public void callMethodInService();}


IService是回调接口,在bind 方法的时候,返回一个继承Binder  并且实现IService接口的对象 即: public class MyBinder extends Binder implements IService。这样更符合Java 面向对象的思想。