使用started Service其他组件不能调用service里面的方法,要实现组件和service之间的方法调用使用Bound Service的方式很容易实现。
Bound Service是一种很典型的C/S(客户端/服务端)模式。客户端(如Activity)发出请求,绑定Service,Service调用onBind()方法返回一个IBinder对象来和Activity进行交互,Activity中要实现一个ServiceConnection接口的实现类对象(可以用匿名内部类的方法),在实现ServiceConnection的实现类的对象时,会重写onServiceConnected()和onServiceDisconnected()方法。
onServiceConnected()会在绑定Sercice时回调。
onServiceDisconnected()会在解除绑定时回调。
当Service被绑定后,就和绑定他的组件共存亡了,就是说当组件被销毁,那service也就凉了。
通过一个简单的例子来看一下:
在MainActivity的onCreate()中调用Service中的方法实现生成随机数。
- 布局:在LinearLayout中添加6个textview,另外在加一个按钮
- 创建一个Service并重写方法
public class BinderService extends Service {
public BinderService() {
}
public class MyBinder extends Binder{
public BinderService getService(){
return BinderService.this;
}
}
@Override
public void onCreate() {
Log.i("mark--onCreate()","绑定时被调用1");
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
Log.i("mark--onbind()","绑定时被调用2");
return new MyBinder();
}
//获取7个随机数放在一个arraylist中
public List getRandomNumbers() {
List list=new ArrayList();
String number="";
for (int i=0;i<7;i++){
int num=new Random().nextInt(33)+1;
if (num<10){
number="0"+String.valueOf(num);
}else{
number=String.valueOf(num);
}
list.add(number);
}
return list;
}
@Override
public void onDestroy() {
Log.i("mark--onunbind()","解除绑定时被调用");
super.onDestroy();
}
}
我们主要看onBind()方法,此方法返回一个IBinder,这个IBinder就是用来和Activity交互要用的
我们需要创建一个内部类public class MyBinder extends Binder{}让他继承Binder,以便我们在onBind()方法中可以返回一个此类的实例。
- MainActivity
public class MainActivity extends Activity {
BinderService binderService;
int [] arrays={R.id.text1,R.id.text2,R.id.text3,R.id.text4,R.id.text5,
R.id.text6,R.id.text7};
ServiceConnection conn=new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i("mark--onSerConnected()","服务绑定时回调");
binderService=((BinderService.MyBinder)service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
Log.i("mark--onSDisconnected()","服务凉时回调");
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button= (Button) findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
List number=binderService.getRandomNumbers();
for (int i=0;i<number.size();i++){
TextView textView= (TextView) findViewById(arrays[i]);
String num=number.get(i).toString();
textView.setText(num);
}
}
});
}
@Override
protected void onStart() {
super.onStart();
Log.i("mark--main:onStart()","程序运行");
Intent intent=new Intent(this,BinderService.class);
bindService(intent,conn,BIND_AUTO_CREATE);
}
@Override
protected void onStop() {
super.onStop();
Log.i("mark--main:onStop()","程序结束");
unbindService(conn);
}
}
在onStart()方法中绑定Service,就是在程序启动时自动绑定。
bindService()方法中需要一个ServiceConnection 对象参数,我们通过匿名内部类的方法创建一个,并重写了onServiceConnected()和onServiceDisconnected()方法。
当服务绑定时回调onServiceConnected()有方法;onServiceDisconnected() 在连接正常关闭的情况下是不会被调用的, 该方法只在Service 被破坏了或者被杀死的时候调用. 例如, 系统资源不足, 要关闭一些Services, 刚好连接绑定的 Service 是被关闭者之一, 这个时候onServiceDisconnected() 就会被调用。