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>