【Android】17.2 Activity与Local Service的绑定
分类:C#、Android、VS2015;
创建日期:2016-03-03
一、简介
如果服务是你的应用程序所私有的,即服务(Service)与客户端(Activity)都在同一个项目中(大部分应用程序的情况都是如此),这种服务称为本地服务。
对于本地服务,应该在继承自Binder的类中创建接口,并从重写的OnBind()方法中返回一个Binder的实例。客户端接收这个Binder对象并用它来直接访问Binder甚至Service中可用的公共(public)方法。
二、示例1运行截图
三、主要设计步骤
1、添加ch1701_main.xml文件
在layout文件夹下添加该文件,模板选择【XML】,因为布局比较简单,就不让它带设计界面了。当然也可以添加ch1701_main.axml文件让其带设计界面。
<?xml version="1.0" encoding="utf-8" ?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:padding="4dip"
android:gravity="center_horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/ch1701_bind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="启动服务绑定">
<requestFocus />
</Button>
<Button
android:id="@+id/ch1701_call"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="调用服务提供的方法">
<requestFocus />
</Button>
<Button
android:id="@+id/ch1701_unbind"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="解除服务绑定" />
</LinearLayout>
2、创建服务—ch1701Service
要创建一个可被绑定的服务(bound service),必须在提供的服务中实现OnBind()回调方法,并在该方法中返回一个IBinder类型的对象,此对象定义了与服务进行通信的接口,该接口用于指明客户端如何与服务进行通信。
ch1701Service.cs文件的代码如下:
using Android.App;
using Android.Content;
using Android.OS;
namespace MyDemos.SrcDemos
{
[Service]
public class ch1701LocalService : Service
{
// 用于让客户端绑定的IBinder接口
private readonly IBinder binder;
// 用于获取随机数
private readonly System.Random r = new System.Random(); public ch1701LocalService()
{
binder = new ch1701LocalBinder(this);
} public override IBinder OnBind(Intent intent)
{
return binder;
} // 声明让客户端调用的公共方法
public int GetRandomNumber()
{
return r.Next(100);
}
} // 因为本服务总是运行于与客户端相同的进程中,因此不需要用IPC进行处理。
public class ch1701LocalBinder : Binder
{
// 客户端可通过它调用服务提供的公共方法
public ch1701LocalService localService { get; private set; } public ch1701LocalBinder(ch1701LocalService service)
{
localService = service;
}
}
}
(1)代码解释
(a)在MyService中包含可供客户端调用的公共方法。
既然是服务,就要在Service中包含可供客户端调用的公共方法,该例子仅仅用GetRandomNumber()方法来演示。当然,也可以通过这些公共方法方返回其它类的实例。
(b)从回调方法OnBind()中返回Binder的实例。
在客户端中,通过在回调方法OnServiceConnected()中接收Binder并调用服务提供的方法,即可实现对绑定的服务进行调用。
ch1701LocalBinder为客户端提供了localService属性,通过该属性得到ch1701LocalService的实例后,客户端就可以通过它调用服务中提供的公共方法(比如调用服务示例代码中的GetRandomNumber()方法)。
(c)注意事项。
服务和客户端之所以必须位于同一个应用程序中(同一个项目中),是为了让客户端能够正确转换(cast)返回的对象并调用对象的API。 另外,服务和客户端也必须位于同一个进程中,因为这种方式不能执行任何跨进程的序列化(marshalling)操作。要实现跨进程的序列化操作,可利用消息传递来实现。
(2)创建继承自Binder的类
要实现可被绑定的服务,除了创建服务外,还需要自定义一个继承自Binder的子类,在该子类中提供一个返回服务实例的方法。该子类是IBinder接口的默认实现。
Binder子类通过返回的Service实例响应客户端请求。
例如,在ch1701Service.cs文件中定义了一个名为ch1701ServiceBind的类,当客户端第1次连接服务时,Android会自动调用服务中提供的OnBind方法。这样以来,客户端就可以通过Service调用服务提供的公共方法了。
3、创建客户端—ch1701BindingActivity.cs
ch1701BindingActivity.cs文件的代码如下:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Widget;
namespace MyDemos.SrcDemos
{
[Activity(Label = "【例17-1】绑定到本地服务")]
public class ch1701BindingActivity : Activity
{
ch1701LocalService mService;
ch1701ServiceConnection mConnection;
bool mBound = false;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.ch1701_main);
mConnection = new ch1701ServiceConnection(this); var btnBind = FindViewById<Button>(Resource.Id.ch1701_bind);
btnBind.Click += delegate
{
if (mBound == false)
{
// 绑定到LocalService
Intent intent = new Intent(this, typeof(ch1701LocalService));
BindService(intent, mConnection, Bind.AutoCreate);
}
Toast.MakeText(this, "已绑定", ToastLength.Short).Show();
}; var btnCall = FindViewById<Button>(Resource.Id.ch1701_call);
btnCall.Click += delegate
{
if(mBound==false)
{
Toast.MakeText(this, "请先绑定", ToastLength.Short).Show();
return;
}
// 注意如果该调用会导致某些操作的挂起,应该在单独的线程中调用它,
// 以免降低activity的性能。
int num = mService.GetRandomNumber();
Toast.MakeText(this, "获取的值为: " + num, ToastLength.Short).Show();
}; var btnUnbind = FindViewById<Button>(Resource.Id.ch1701_unbind);
btnUnbind.Click += delegate
{
// 与服务解除绑定
if (mBound == true)
{
UnbindService(mConnection);
Toast.MakeText(this, "绑定已解除", ToastLength.Short).Show();
}
}; } public class ch1701ServiceConnection : Java.Lang.Object, IServiceConnection
{
private ch1701BindingActivity activity;
public ch1701ServiceConnection(ch1701BindingActivity activity)
{
this.activity = activity;
} public void OnServiceConnected(ComponentName name, IBinder service)
{
ch1701LocalBinder binder = (ch1701LocalBinder)service;
activity.mService = binder.localService;
activity.mBound = true;
} public void OnServiceDisconnected(ComponentName name)
{
activity.mBound = false;
}
}
}
}
(1)代码解释
该例子展示了客户端如何利用 ServiceConnection 和 OnServiceConnected() 回调方法绑定到服务。
(2)将客户端绑定到服务
客户端可以通过调用BindService() 方法来绑定服务。当客户端完成交互时,可调用UnbindService()来解除绑定。
调用BindService() 方法来绑定服务时,必须提供一个 ServiceConnection 的实现代码,用于监控与服务的连接。
BindService() 将会立即返回,没有返回值。但是Android系统在创建客户端与服务之间的连接时,会自动调用 ServiceConnection 中的 OnServiceConnected() 方法传递一个 IBinder ,客户端利用它即可与服务进行通信。
ch1701ServiceConnection类负责提供客户端和服务之间的调用接口,注意该类实现了IServiceConnection接口,由于ServiceConnection类是通过Java定义的,所以ch1701ServiceConnection类必须继承自Java.Lang.Object。
BindService方法实现的功能是:如果存在绑定,就使用Bind.AutoCreate值自动创建服务(Android 5.0及更高版本才有此选项)。该方法是一个异步调用,如果没有可绑定的服务该方法将返回false,如果有可绑定的服务,则通过回调将建立的连接发送到ch1701ServiceConnection类中的OnServiceConnected()方法。
MyServiceConnection类继承自ServiceConnection类,在这个类中,重写了OnServiceConnected方法。在这种情况下,IBinder是MyServiceBinder的一个实例。MyServiceBinder用于获取对MyService的引用,以便客户端可以利用它调用服务中定义的方法。
注意在MyServiceConnection的构造函数中,将MainActivity的实例传递到本类中声明的activity(例子中只是以MainActivity为例,但也可以是其他的Activity),这是为了可以在Activity中通过它自身定义的OnServiceConnected回调方法得到对服务的引用,这样以来,Activity就可以调用服务中提供的方法了。
(3)调用服务提供的方法
客户端通过Binder实例获取被绑定的服务的引用后,就可以调用服务中提供的方法了。在这个例子中,ch1701Service服务只定义了一个GetRandomNumber()方法。一旦Activity通过OnServiceConnected方法实现了绑定,这个Activity就可以利用binder来获取对服务的引用,随后就可以调用服务中提供的GetRandomNumber()方法了。
(4)取消服务绑定(Unbinding from the Service)
客户端(Activity)完成对服务的调用后,必须取消对该服务的绑定(即:在不使用服务时要及时关闭服务)。服务断开连接后,会自动调用ServiceConnection类的OnServiceDisconnected方法。
要解除被绑定的服务,客户端调用UnbindService方法即可,通过它可传递在绑定中使用的ServiceConnection实例。
如果没有Activity通过StartService方法调用该服务,也没有其他客户端绑定到该服务,则安卓系统将自动关闭该服务。
【Android】17.2 Activity与Local Service的绑定的更多相关文章
- Android中Local Service最本质的作用是什么?
把Service等同于thread或process是一个非常常见的误解.需要强调又强调的第一点是,Android的Service是一个Context,并不必然等于一个额外的thread.如果你有仔细看 ...
- 【转】 Pro Android学习笔记(七七):服务(2):Local Service
目录(?)[-] Local service代码 调用Local ServiceLocal Service client代码 AndroidManifestxml定义Serviceacitivty的l ...
- Android开机启动Activity或者Service方法
本文出自 “Bill_Hoo专栏” 博客,请务必保留此出处http://billhoo.blog.51cto.com/2337751/761230 这段时间在做Android的基础开发,现在有一需求是 ...
- android 中activity调用本地service中的方法。
1.自定义一个接口,暴露服务中的方法 public interface IService { /**服务中对外暴露的方法 */ void methodInService();} 2.自定一 ...
- Android开机启动Activity或者Service方法(转载)
这段时间在做Android的基础开发,现在有一需求是开机启动,按照网上某些博文教程做了下,始终不成功,一开机总是提示所启动的应用程序意外终止,于是参考了Android SDK doc,终于解决问题,下 ...
- Android Activity与远程Service的通信学习总结
当一个Service在androidManifest中被声明为 process=":remote", 或者是还有一个应用程序中的Service时,即为远程Service, 远程的意 ...
- Android 综合揭秘 —— 全面剖释 Service 服务
引言 Service 服务是 Android 系统最常用的四大部件之一,Android 支持 Service 服务的原因主要目的有两个,一是简化后台任务的实现,二是实现在同一台设备当中跨进程的远程信息 ...
- Android中半透明Activity效果另法
Android中的Activity有没有类似于像Windows程序样的窗口式显示呢? 答案当然是有. 下图就是一个窗口式Activity的效果图: 下面就说说实现过程: 首先看看AndroidMani ...
- Android application 和 activity 标签详解
extends:http://blog.csdn.net/self_study/article/details/54020909 Application 标签 android:allowTaskRep ...
随机推荐
- JBOSS启动报错解决方案
同一个jboss下不可以放不同的项目包,否则报错: 注意:如果后期使用,注意删除上图的本地文件,重新加载即可.
- Java从零开始学十二(构造方法)
一.构造方法 构造方法的主要目的是为类中的属性初始化 二.构造方法的定义格式 class 类名称{ 访问权限 类名称(类型1 参数1,类型2 参数2,…){ 程序语句 ; … // 构造方法没有 ...
- 1z0-052 q209_4
4: You have two tables with referential integrity enforced between them. You need to insert data to ...
- Oracle查询备注信息
查询表的备注信息: SELECT TABLE_NAME, TABLE_TYPE, COMMENTS FROM USER_TAB_COMMENTS WHERE TABLE_NAME = 'MR_DEPT ...
- [Python]网络爬虫(九):百度贴吧的网络爬虫(v0.4)源码及解析
转自:http://blog.csdn.net/pleasecallmewhy/article/details/8934726 百度贴吧的爬虫制作和糗百的爬虫制作原理基本相同,都是通过查看源码扣出关键 ...
- [Python]网络爬虫(六):一个简单的百度贴吧的小爬虫
转自:http://blog.csdn.net/pleasecallmewhy/article/details/8927832 # -*- coding: utf-8 -*- #----------- ...
- 对opencv MeanShift 融合矩形框的改进
OPENCV 中的代码改进.当然要依据自己的实际情况来,OPENCV 中行人检測有两种矩形框的融合算法.这里仅仅对meanshift 方法做改进 假设有更好的方法.希望能够跟我讲下. 对于去除重合部分 ...
- 推荐10 款 SVG 动画的 JavaScript 库
SVG 通常可以用作跨分辨率视频.这意味着在一块高分屏幕上不会降低图片的锐度.此外,你甚至可以让SVG动起来,通过使用一些javascript类库.下面,我们分享一些javascript类库,这些类库 ...
- 转:【HTTP】常见错误码说明
一些常见的状态码为: 200 - 服务器成功返回网页404 - 请求的网页不存在503 - 服务不可用详细分解: 1xx(临时响应)表示临时响应并需要请求者继续执行操作的状态代码. 代码 说明100 ...
- ASP.NET DataBase
//数据库操作 public class DataBase { private SqlConnection conn;//数据库连接对象 #region 打开数据库连接 private void Op ...