上几节,我们学习如何用StartServer启动一个服务,用bindServer去绑定一个服务,以及服务的生命周期,以及什么是IntentService。
或许有读者会发现,我们BindServer中的第二个参数也就是ServiceConnection这个方法在将用bindService时好像没用到。那本节课就学习。
那我们先说个事,上大学的时候,我学习不好,还是那种经常旷课的同学。长期下去,老师跟前就混的不好了。 有次班里评选党员,我就想竞争一下,但是由于我经常不上课的同学,自然几率就小,所以我就想到走后门。 咋给导员点钱呗,反正导员是贪官,是贪官哪有不贪的。可是我不认识导员啊,那怎么办? 但是我舍友那是导员之前的红人啊,可以通过我舍友把钱给导员,然后让导员给我整个党员呗。
大概流程是这样的:
那我们把这个转化为代码:
这个就相当与我们用于一个Activity去启动一个服务,但是服务有个方法,Activity想用但是却拿不到,只能通过第三方去帮他拿。
上图中Activity就是我, 而Seriver就是贪官导员,只有导员能给你一个名额让你成为党员,但是你不认识导员,所以就得去找你舍友,也就是导员的亲信。
那问题现在转话为: 我要找我舍友,也就是导员的亲信了。
那两种启动服务的方式,那种服务当创建后能返回给你这个亲信呢? 明显startService启动的服务是没有的。但是bindService启动服务有:
代码语言:javascript复制 @Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
就是bindService启动服务后,通过return返回值,默认情况下是null的。
既然分析到,bindService是可以返回到服务的,担不是服务本身,只是服务的代理而已。
代码语言:javascript复制public class MainActivity extends Activity {
private Intent intent;
private MyServiceConn conn;
SheYou me;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
intent = new Intent(this, DangYuanService.class);
conn = new MyServiceConn();
//绑定服务
bindService(intent, conn, BIND_AUTO_CREATE);
}
//我想成为党员的方法
public void toDoDangyuan(View v)
{
//调用舍友的方法
me.ToBeDangYuan();
}
class MyServiceConn implements ServiceConnection
{
//当服务连接成功后调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 得到服务的代理
me = (SheYou) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
}
服务代码:
代码语言:javascript复制public class DangYuanService extends Service {
@Override
public IBinder onBind(Intent intent) {
//返回服务的代理,也就是贪官导员的亲信
return new SheYou();
}
//舍友独有的能给我办党员的方法
class SheYou extends Binder
{
//中间中(舍友)独有的方法,让你成为党员
public void ToBeDangYuan()
{
DangYuan();
}
}
//服务自己的方法,也即是导员的权利
public void DangYuan()
{
Log.i("DangYuanService", "只需1000元就能成为党员!");
}
}
运行效果就知道了:我舍友找到导员,导员说“只需1000元吉行”。 看看,导员多贪
我当时就想举报贪官,可是我还想着毕业呢。 就没举报贪官。
接着,我们导员还有个嗜好,那就是喝酒,当然了我舍友那必须要参加的。
代码语言:javascript复制 class SheYou extends Binder
{
//中间中(舍友)独有的方法,让你成为党员
public void ToBeDangYuan()
{
DangYuan();
}
public void HeJiu()
{
Log.i("DangYuanService", "陪导员喝酒!!!!");
}
}
给我舍友加上一个新方法,陪导员喝酒
当然了陪导员喝酒,那只有导员的亲信才能参加,像我这种级别的人,那是不能参加的。当然也就无权知道了
代码语言:javascript复制 //我想成为党员的方法
public void toDoDangyuan(View v)
{
//调用舍友的方法
me.ToBeDangYuan();
me.HeJiu();
}
那现在我访问喝酒的方法还是ok的。按道理我是无权知道的。 那就不行了。那就对服务修改
这时候我们创建一个专门只有当党员的借口:
代码语言:javascript复制public interface DangYuanInterface {
//只有一个方法,你能知道,那就是党员的事情
public void ToBeDangYuan();
}
然后让舍友,也就是中间人,实现这个接口
代码语言:javascript复制 class SheYou extends Binder implements DangYuanInterface
{
//中间中(舍友)独有的方法,让你成为党员
public void ToBeDangYuan()
{
DangYuan();
}
public void HeJiu()
{
Log.i("DangYuanService", "陪导员喝酒!!!!");
}
}
然后,Activity中定义一个党员的接口
代码语言:javascript复制DangYuanInterface dangyuan;
然后得到这个中间人对象:
代码语言:javascript复制 public void toDoDangyuan(View v)
{
//调用舍友的方法
dangyuan.ToBeDangYuan();
}
class MyServiceConn implements ServiceConnection
{
//当服务连接成功后调用
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 得到服务的代理
dangyuan = (DangYuanInterface) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
}
}
这时候你只能知道关于党员的事情,别的事情你无权过问。 这样以后想需要获取服务里的方法,就可以通过onBind的返回值得到服务的代理,记住不是服务的本身。通常情况下把服务的代理或者中间人,一般把中间人独有的方法抽成接口。