Android之Service(三):活动和服务进行通信
在活动中指挥服务
思路:首先要让活动和服务进行绑定,通过bindService()方法使得Activity和Service绑定在一起。注意bindService()方法要求传入Binder对象和ServiceConnection ,这就表示Binder和ServiceConnection 建立了联系。然后在Service中创建一个专门的Binder对象来提供相应的功能,之后在onBind() 方法中返回这个Binder对象到Activity中的ServiceConnection的onServiceConnected()方法中。这样在Activity中实现ServiceConnection时就可以在onServiceConnected()方法中使用Service中的Binder对象提供的功能。这样在活动中就可以指挥服务了,也就实现了活动与服务通信。
实例:希望在MyService里提供一个下载功能,然后在活动中可以决定何时开始下载,以及随时查看下载进度。
MyService代码如下:
public class MyService extends Service {
//new一个DownloadBinder实例
private DownloadBinder mBinder = new DownloadBinder();
//创建一个DownloadBinder提供开始下载和获取进度两个方法
class DownloadBinder extends Binder{
public void startDownload() {
//开始下载
Log.d("MyService", "startDownload executed");
}
public int getProgress() {
//获取进度
Log.d("MyService", "getProgress executed");
return 0;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
//返回DownloadBinder实例
return mBinder;
}
}
可以看到,首先专门创建了一个DownloadBinder类继承Binder,然后在它的内部提供了开始下载以及查看下载进度的方法。当然这只是两个模拟方法,并没有实现真正的功能,在这两个方法中分别打印了一行日志。接着,在MyService中创建了DownloadBinder的实例,然后在onBind()方法里返回了这个实例,这个实例将会被传到后面的ServiceConnection中的onServiceConnection()方法中。
假设已经在MainActivity的布局文件activity_main.xml中添加了2个按钮。
MainActivity代码如下:
public class MainActivity extends Activity implements View.OnClickListener {
private Button bind;
private Button unbind;
//声明一个MyService.DownloadBinder的实例
private MyService.DownloadBinder downloadBinder;
//创建ServiceConnection的实例connection,并实现ServiceConnection
private ServiceConnection connection=new ServiceConnection() {
//连接上服务时运行该方法
//其中IBinder service是从Service中onBind()方法中返回的
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//获取DownloadBinder实例
downloadBinder = (MyService.DownloadBinder) service;
//调用执行开始下载和获得进程这两个方法
downloadBinder.startDownload();
downloadBinder.getProgress();
}
//与服务断开连接时运行该方法
@Override
public void onServiceDisconnected(ComponentName name) {
//执行一些收尾的工作
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bind = (Button) findViewById(R.id.bind);
unbind = (Button) findViewById(R.id.unbind);
bind.setOnClickListener(this);
unbind.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bind:
//创建指向MyService的Intent实例
Intent bindIntent = new Intent(this, MyService.class);
//绑定服务
bindService(bindIntent, connection, BIND_AUTO_CREATE);
break;
case R.id.unbind:
//解绑服务
unbindService(connection);
break;
}
}
}
可以看到,这里首先创建了一个ServiceConnection的匿名类,在里面重写了onServiceConnected()方法和 onServiceDisconnected()方法,这两个方法分别会在活动与服务成功绑定以及解除绑定的时候调用。在onServiceConnected()方法中,通过向下转型得到了DownloadBinder的实例,有了这个实例,活动和服务之间的关系就变得非常紧密了。
现在可以在活动中根据具体的场景来调用DownloadBinder中的任何public方法,即实现了指挥服务干什么,服务就去干什么的功能。这里仍然只是做了个简单的测试,在onServiceConnected()方法中调用了DownloadBinder的startDownload()和getProgress()方法。当然,现在活动和服务其实还没进行绑定呢,这个功能是在bind按钮的点击事件里完成的。可以看到,这里是构建出了一个Intent对象,然后调用bindService()方法将MainActivity和MyService 进行绑定。bindService()方法接收三个参数,第一个参数就是刚刚构建出的Intent对象,第二个参数是前面创建出的ServiceConnection的实例,第三个参数则是一个标志位,这里传入BIND_AUTO_CREATE表示在活动和服务进行绑定后自动创建服务。这会使得MyService中的onCreate()方法得到执行,但onStartCommand()方法不会执行。
然后如果想解除活动和服务之间的绑定只要调用一下unbindService()方法就可以了,这也是unbind按钮的点击事件里实现的功能。
另外需要注意,任何一个服务在整个应用程序范围内都是通用的,即MyService不仅可以和MainActivity绑定,还可以和任何一个其他的活动进行绑定,而且在绑定完成后它们都可以获取到相同的DownloadBinder实例。
作者:lj2012sy
来源:CSDN
原文:https://blog.csdn.net/lj2012sy/article/details/51679564
版权声明:本文为博主原创文章,转载请附上博文链接!