Service在Android的四大组件中,和Activity最为相似,都是从Context派生出来的,区别在于前者一直在后台运行,它没有界面。
一、Service简介
1、创建、配置Service
开发Service需要两个步骤:
(1)定义一个继承Service的子类;
(2)在manifest.xml文件中配置该Service。
例如:
配置Service和Activity很相似,甚至不用label,因为Service总是在后台,label对其没有什么意义。
<service android:name=".MyService"> <intent-filter> <action android:name="com.xsj.SERVICE" /> </intent-filter> </service>
2、Service定义的系列生命周期方法:
(1)abstract IBind onBind(Intent intent):Service子类必须实现的方法,返回一个IBind对 象,应用程序可通过该对象与Service通信;
(2)onCreate():当Service第一次被创建后将立即回调该方法;
(3)onDestory():当Service被关闭之前回调该方法;
(4)onUnbind(Intent intent):当Service上绑定的所有客户端都断开连接时回调该方法;
(5)onStartCommand(Intent intent, int flags, int startId):早期为onStart()方法,每次客 户端调用startService(intent)方法启动该Service时都会回调该方法。
3、启动和停止Service
运行Service有两种方式:
(1)通过Context的startService()方法,启用Service,访问者与Service之间没有关联,如果访问者退出,Service仍然运行,对应的为stopService()关闭Service;
(2)通过Context的bindService()方法,启用Service,访问者与Service绑定在一起,如果访问者一旦退出,那么该Service也就终止了。
注:每当Service被创建时会回调onCreat()方法,每次Service被启动时会回调onStart()方法;
多次启动一个已有的Service组件将不会回调onCreate()方法,但是每次启动都会回调onStart()方法。
二、绑定本地Service并与之通信
如果Service和访问者之间需要进行方法调用或者数据交换,那么应该使用bingService()和unbindService()方法。
1、bindService(Intent service, ServiceConnection conn, int flags):
(1)service:该参数通过Intent指定要启动的Service;
(2)conn:该参数是一个ServiceConnection对象,该对象用于监听访问者与Service之间的连接情 况,根据连接情况回调其对应的方法;
(3)flags:指定绑定时是否自动创建Service(如果Service还没有创建),0表示不自动创建, BIND_AUTO_CREATE表示自动创建。
2、通信原理
开发自己的Service时,必须提供一个IBinder onBind(intent)方法,该方法返回的IBinder对象将会传给ServiceConnection对象里的onServiceConnected()方法中的参数,这样访问者就通过该IBinder对象与Service进行通信。
实际开发中通常会采用继承Binder(IBinder的实现类)的方式来实现自己的IBinder对象。
三、项目实例
MyService是一个Service,MyActivity和它进行通信
MyService:
package com.xsj.service; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; public class MyService extends Service { private int count = 0; private MyBinder binder = new MyBinder(); private boolean flag = true; /** * 通过继承Binder来实现IBinder */ public class MyBinder extends Binder { // 这里返回了Service运行的状态,即计数值 public int getCount() { return count; } } /** * 必须实现的方法,这里返回了IBinder对象 */ @Override public IBinder onBind(Intent intent) { return binder; } /** * Service被创建时回调该方法 */ @Override public void onCreate() { showCount(); } /** * Service被断开连接时回调的方法 */ @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } /** * Service被关闭之前回调的方法 */ @Override public void onDestroy() { flag = false; super.onDestroy(); } /** * 计数操作 */ private void showCount() { new Thread() { @Override public void run() { while (flag) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } count++; } } }.start(); } }MyActivity:
package com.xsj.service; import android.app.Activity; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MyActivity extends Activity { private Button start; private Button stop; private Button getCount; MyService.MyBinder binder; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); start = (Button) findViewById(R.id.start); stop = (Button) findViewById(R.id.stop); getCount = (Button) findViewById(R.id.get_count); final Intent intent = new Intent(); intent.setAction("com.xsj.SERVICE"); start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 绑定指定的service bindService(intent, conn, Service.BIND_AUTO_CREATE); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 在这里解除和service的绑定 unbindService(conn); } }); getCount.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Toast.makeText(MyActivity.this, "来自service - " + binder.getCount(), Toast.LENGTH_LONG) .show(); } }); } /** * ServiceConnection对象 */ private ServiceConnection conn = new ServiceConnection() { // 当activity和service断开连接时回调该方法 @Override public void onServiceDisconnected(ComponentName name) { } // 当activity和service连接成功时回调该方法 @Override public void onServiceConnected(ComponentName name, IBinder service) { // 获取service的onBind()方法所返回的MyBinder对象 binder = (MyService.MyBinder) service; } }; @Override protected void onResume() { super.onResume(); } @Override protected void onDestroy() { super.onDestroy(); } }运行时,点击开始按钮,启动Service,count开始增加,点击获取数据按钮,返回count的当前值,点击停止按钮,解除绑定。
注:与采用startService()启动Service所不同的是,多次调用bindService()方法并不会执行重复绑定,即无论点击多少次开始按钮,系统只会回调Service的onBind()方法一次。