通过 前面 的学习,可以发现使用 start 方式开启 Service 非常简单,但是它有一个技大的弊端,没有办法与开启者进行通信。为了解决这个问题,我们一般会使用 bind 方式来定 Service 。以 bind 方式创建与绑定 Service 的步骤在 之前 也已讲述,此处将 用 一个实例来进行讲解。 1 、 创建一个继承 Service 类的子类 My Service 类,由于是采用 bind 方式绑定 Service , 因此 My Service 类与 前文以 start 方式开启 Service 而创建的继承 Service 类的子类有很大不同。 前文说过,采用此种方式绑定 Servce 时会回调 onBind () 方法,此方法会返回一个 IBi nd 类的对象。一般情况下,如果我们在某个 Activity 中绑定了此 Service ,就会从 ServiceC onn ecti o n 类 onServiceConnected ( ComponentName name , IBinder service ) 方法中获取到 onBind () 方法返 回 的 IBind 类的对象。 Activity 与 Service 可以进行通信,利用的就是这个 IBind 类的对象。 所以,我们可以建立一个 IBind 类的子类,并在该类中封装 Service 对象,并在 onBi n d () 方法中返回此类的对象。这样一来,在 Activity 中就可以对 Service 进行操作了。 My Servic e 类代码如下 ∶ package com.rfstar.servicetest2; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; import android.util.Log; public class MyService extends Service { private String message; private boolean isrunning = true; private IBinder binder = new MyBinder(); private MyService.ServiceThread serviceThread=new MyService.ServiceThread(); private Thread thread; @Override public IBinder onBind(Intent intent) { Log.i("service", "onBind"); thread = new Thread(serviceThread); //开启一个线程 thread.start(); /**返回一个可以在Activity的onServiceConnected()方法中接收的binder对象 * 它是Activity和Service通信的桥梁 * 在Activity中通过这个bind对象可以得到Service的实例引用 * 通过获取的Service实例就可以调用相关方法和属性 */ return binder; } @Override public void onCreate() { Log.i("service", "oncreate"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.i("service", "onStartCommand"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { Log.i("service", "onUnbind"); return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); //结束run方法的循环 serviceThread.flag = false; Log.i("service", "onDestroy"); } class ServiceThread implements Runnable { //用volatile修饰保证变量在线程间的可见性 volatile boolean flag = true; @Override public void run() { Log.i("service", "thread开始运行"); int i = 1; while (flag) { if (mOnDataCallback != null) { //通过线程模拟真实场景,循环改变数据 mOnDataCallback.onDataChange(message + i); } i++; try { //间隔2秒调用一次函数 Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } } } public class MyBinder extends Binder{ public void setData(String message) { //从Activity传入message值 MyService.this.message=message; } public MyService getService() { /** * 返回当前MyService对象 * 当Activity中获取binder类的实例后 * 可以通过此方法获取Service类实例 */ return MyService.this; } } private OnDataCallback mOnDataCallback=null; public void setmOnDataCallback(OnDataCallback mOnDataCallback) { this.mOnDataCallback = mOnDataCallback; } public interface OnDataCallback{ void onDataChange(String message); } } 除了上面所说的 IBind 类之外,在此 Service 类中还建立了一个接口 OnDataCal l back ,用 来 进行数据的回调。 2 、 在 AndroidManifest . xml 中配置 Service 与前例相同,在 AndroidManifest . xml 中加入如下代码即可 ∶ 3、 通过 Context 调用 bindService ( Intent intent , ServiceConn e ction serviceConnection , int flags ) 方法来绑定 Service. 调用 unBindService ( ServiceConnection serviceConnection ) 方法来解绑 Service 。 可以发现不管是绑定服务还是解绑服务都需传入一个 ServiceConnection 类的对象作为参。 ServiceConnection 类有两个比较重要的回调方法 ∶onServiceConnected ( ComponentName n a me , IBinder service ) 与 onServiceDisconnected ( ComponentName name ) ,这两个方法中前者是当 Actviy 与 Service 绑定时的回调方法,后者是解绑时的回调方法。一般情况下我们会在前个方法中获取 IBinder 类的对象,并通过该对象获取 Service 类的实例,然后对 Service 进行操作,而在后一个方法中主要就是做一些清理性工作,比如销毁对象。 本实例中为了展现出 Service 与 Activity 真正在做通信,加入了一个 TextView ,当 Main Actity 获取 Service 中的数据时,对该 TextView 的值进行修改。实例中布局文件在前例的 acivity_main.xml 文件基础上修改,大同小异,代码如下 ∶