MainActivity如下:
package cc.testservice2; 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.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; /** * Demo描述: * 采用bindService()方法启动服务 * 该Demo描述的本地服务,即服务和访问者在同一进程 * * 客户端总结: * 客户端(此处为MainActivity)的核心目的: * 得到服务返回来的Binder对象,然后利用此Binder对象调用服务里的相关方法 * * 详细步骤: * 1 写一个ServiceConnectionImpl类实现了ServiceConnection接口 * 即 private final class ServiceConnectionImpl implements ServiceConnection * 2 新建ServiceConnectionImpl类的对象conn.然后利用Context激活服务,与服务建立连接 * 即 this.bindService(service, conn, this.BIND_AUTO_CREATE); * 3 覆写ServiceConnectionImpl类的public void onServiceConnected(ComponentName name, IBinder service) * 方法,该为一个回调方法!!!!当客户端与服务建立连接后,服务端的public IBinder onBind(Intent intent)()方法 * 就会返回一个IBinder对象给客服端.此IBinder对象就是方法 * public void onServiceConnected(ComponentName name,IBinder service)中的service * 4 利用服务器返回的IBinder对象调用服务中的方法 * * 注意: * 1 在绑定和解除绑定用的都是从mServiceConnectionImpl对象,它的类实现了ServiceConnection接口 * 2 注意不但要重写MainActivity的onCreate()里与服务建立连接,而且还要重写Activity的 onDestroy()方法! * 以便在此Activity退出时,关闭与服务的连接 * 3 在这个小应用中为什么要定义一个接口呢? * 因为服务要返回给MainActivity一个Binder对象,MainActivity接收此对象。此对象是在服务里内部类的对象。 * 但是一般来说内部类是私有的。所以在MainActivity里不可能new()一个内部类对象来接收此对象 * 所以在此定义了接口--->用接口来接收Binder对象.这样做而且很规范,将业务抽象成接口. * * 服务端总结: * 1 自定义服务类ServiceSubclass继承自Service * 2 写一个自定义的内部类BinderSubclass实现了业务接口,且继承自Binder * 3 重写Service的public IBinder onBind(Intent intent)方法,返回一个IBinder对象. * 即这里的BinderSubclass类对象 */ public class MainActivity extends Activity { TextView mNumberTextView; TextView mResultTextView; Button mSearchButton; ServiceConnectionImpl mServiceConnectionImpl; QueryInterface mBinder; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //用于接收服务返回的Binder对象 mServiceConnectionImpl=new ServiceConnectionImpl(); mNumberTextView=(TextView) findViewById(R.id.numberEditText); mResultTextView=(TextView) findViewById(R.id.resultTextView); mSearchButton=(Button) findViewById(R.id.searchButton); mSearchButton.setOnClickListener(new ButtonOnClickListener()); Intent intent=new Intent(this,ServiceSubclass.class); //当Activity启动的时候就启动服务 bindService(intent, mServiceConnectionImpl, this.BIND_AUTO_CREATE); } private class ButtonOnClickListener implements OnClickListener{ public void onClick(View v) { String number=mNumberTextView.getText().toString(); String result=mBinder.queryByNumber(Integer.valueOf(number)); mResultTextView.setText(result); } } //绑定服务和解除服务 private final class ServiceConnectionImpl implements ServiceConnection{ //绑定服务时,此方法调用 public void onServiceConnected(ComponentName name, IBinder service) { mBinder=(QueryInterface) service; } //解除服务时,此方法调用 public void onServiceDisconnected(ComponentName name) { mBinder=null; } } //解除与服务的连接 protected void onDestroy() { unbindService(mServiceConnectionImpl); super.onDestroy(); } }
ServiceSubclass如下:
package cc.testservice2; import android.app.Service; import android.content.Intent; import android.os.Binder; import android.os.IBinder; /** * 服务端总结: * 1 自定义服务类ServiceSubclass继承自Service * 2 写一个自定义的内部类BinderSubclass实现了业务接口,且继承自Binder * 3 重写Service的public IBinder onBind(Intent intent)方法,返回一个IBinder对象. * 即这里的BinderSubclass类对象 */ public class ServiceSubclass extends Service { private String[] names = new String[] { "小明", "小王", "小杨", "小李", "小强" }; BinderSubclass mBinderSubclass = new BinderSubclass(); @Override public IBinder onBind(Intent intent) { return mBinderSubclass; } // queryByNumber就是接口里的业务方法. //一般来讲将业务抽象为一个接口,然后去实现接口,比如此处。 // 注意:BinderSubclass继承自Binder也实现了业务接口 private final class BinderSubclass extends Binder implements QueryInterface { public String queryByNumber(int number) { return query(number); } } //服务内部的方法 public String query(int i) { if (i > 0 && i < 6) { return names[i - 1]; } return "查询错误,请再次输入"; } }
QueryInterface如下:
package cc.testservice2; //业务接口 public interface QueryInterface { public String queryByNumber(int number); }
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" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="请输入1到5的数字" /> <EditText android:id="@+id/numberEditText" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/searchButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="查询" /> <TextView android:id="@+id/resultTextView" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>