android Service Binder交互通信实例.docx
- 文档编号:8117486
- 上传时间:2023-01-28
- 格式:DOCX
- 页数:16
- 大小:18.19KB
android Service Binder交互通信实例.docx
《android Service Binder交互通信实例.docx》由会员分享,可在线阅读,更多相关《android Service Binder交互通信实例.docx(16页珍藏版)》请在冰豆网上搜索。
androidServiceBinder交互通信实例
androidSDK提供了Service,用于类似*nix守护进程或者windows的服务。
Service有两种类型:
1.本地服务(LocalService):
用于应用程序内部
2.远程服务(RemoteSercie):
用于android系统内部的应用程序之间
前者用于实现应用程序自己的一些耗时任务,比如查询升级信息,并不占用应用程序比如Activity所属线程,而是单开线程后台执行,这样用户体验比较好。
后者可被其他应用程序复用,比如天气预报服务,其他应用程序不需要再写这样的服务,调用已有的即可。
编写不需和Activity交互的本地服务示例
本地服务编写比较简单。
首先,要创建一个Service类,该类继承android的Service类。
这里写了一个计数服务的类,每秒钟为计数器加一。
在服务类的内部,还创建了一个线程,用于实现后台执行上述业务逻辑。
packagecom.easymorse;
importandroid.app.Service;
importandroid.content.Intent;
importandroid.os.IBinder;
importandroid.util.Log;
publicclassCountServiceextendsService{
privatebooleanthreadDisable;
privateintcount;
@Override
publicIBinderonBind(Intentintent){
returnnull;
}
@Override
publicvoidonCreate(){
super.onCreate();
newThread(newRunnable(){
@Override
publicvoidrun(){
while(!
threadDisable){
try{
Thread.sleep(1000);
}catch(InterruptedExceptione){
}
count++;
Log.v("CountService","Countis"+count);
}
}
}).start();
}
@Override
publicvoidonDestroy(){
super.onDestroy();
this.threadDisable=true;
Log.v("CountService","ondestroy");
}
publicintgetCount(){
returncount;
}
}
需要将该服务注册到配置文件AndroidManifest.xml中,否则无法找到:
xmlversion="1.0"encoding="utf-8"?
>
android=" package="com.easymorse"android: versionCode="1"android: versionName="1.0"> icon="@drawable/icon"android: label="@string/app_name"> name=".LocalServiceDemoActivity" android: label="@string/app_name"> name="android.intent.action.MAIN"/> name="android.intent.category.LAUNCHER"/> name="CountService"/> minSdkVersion="3"/> 在Activity中启动和关闭本地服务。 packagecom.easymorse; importandroid.app.Activity; importandroid.content.Intent; importandroid.os.Bundle; publicclassLocalServiceDemoActivityextendsActivity{ /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); this.startService(newIntent(this,CountService.class)); } @Override protectedvoidonDestroy(){ super.onDestroy(); this.stopService(newIntent(this,CountService.class)); } } 可通过日志查看到后台线程打印的计数内容。 编写本地服务和Activity交互的示例 上面的示例是通过startService和stopService启动关闭服务的。 适用于服务和activity之间没有调用交互的情况。 如果之间需要传递参数或者方法调用。 需要使用bind和unbind方法。 具体做法是,服务类需要增加接口,比如ICountService,另外,服务类需要有一个内部类,这样可以方便访问外部类的封装数据,这个内部类需要继承Binder类并实现ICountService接口。 还有,就是要实现Service的onBind方法,不能只传回一个null了。 这是新建立的接口代码: packagecom.easymorse; publicinterfaceICountService{ publicabstractintgetCount(); } 修改后的CountService代码: packagecom.easymorse; importandroid.app.Service; importandroid.content.Intent; importandroid.os.Binder; importandroid.os.IBinder; importandroid.util.Log; publicclassCountServiceextendsServiceimplementsICountService{ privatebooleanthreadDisable; privateintcount; privateServiceBinderserviceBinder=newServiceBinder(); publicclassServiceBinderextendsBinderimplementsICountService{ @Override publicintgetCount(){ returncount; } } @Override publicIBinderonBind(Intentintent){ returnserviceBinder; } @Override publicvoidonCreate(){ super.onCreate(); newThread(newRunnable(){ @Override publicvoidrun(){ while(! threadDisable){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ } count++; Log.v("CountService","Countis"+count); } } }).start(); } @Override publicvoidonDestroy(){ super.onDestroy(); this.threadDisable=true; Log.v("CountService","ondestroy"); } /*(non-Javadoc) *@seecom.easymorse.ICountService#getCount() */ publicintgetCount(){ returncount; } } 服务的注册也要做改动,AndroidManifest.xml文件: xmlversion="1.0"encoding="utf-8"? > android=" package="com.easymorse"android: versionCode="1"android: versionName="1.0"> icon="@drawable/icon"android: label="@string/app_name"> name=".LocalServiceDemoActivity" android: label="@string/app_name"> name="android.intent.action.MAIN"/> name="android.intent.category.LAUNCHER"/> name="CountService"> name="com.easymorse.CountService"/> minSdkVersion="3"/> Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。 packagecom.easymorse; importandroid.app.Activity; importandroid.content.ComponentName; importandroid.content.Intent; importandroid.content.ServiceConnection; importandroid.os.Bundle; importandroid.os.IBinder; importandroid.util.Log; publicclassLocalServiceDemoActivityextendsActivity{ privateServiceConnectionserviceConnection=newServiceConnection(){ @Override publicvoidonServiceConnected(ComponentNamename,IBinderservice){ countService=(ICountService)service; Log.v("CountService","onserivceconnected,countis" +countService.getCount()); } @Override publicvoidonServiceDisconnected(ComponentNamename){ countService=null; } }; privateICountServicecountService; /**Calledwhentheactivityisfirstcreated.*/ @Override publicvoidonCreate(BundlesavedInstanceState){ super.onCreate(savedInstanceState); setContentView(R.layout.main); this.bindService(newIntent("com.easymorse.CountService"), this.serviceConnection,BIND_AUTO_CREATE); } @Override protectedvoidonDestroy(){ this.unbindService(serviceConnection); super.onDestroy(); //注意先后 } } 编写传递基本型数据的远程服务 上面的示例,可以扩展为,让其他应用程序复用该服务。 这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。 这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。 扩展名为aidl而不是java。 可用上面的ICountService改动而成ICountSerivde.aidl,eclipse会自动生成相关的java文件。 packagecom.easymorse; interfaceICountService{ intgetCount(); } 编写服务(Service)类,稍有差别,主要在binder是通过远程获得的,需要通过桩(Stub)来获取。 桩对象是远程对象的本地代理。 packagecom.easymorse; importandroid.app.Service; importandroid.content.Intent; importandroid.os.IBinder; importandroid.os.RemoteException; importandroid.util.Log; publicclassCountServiceextendsService{ privatebooleanthreadDisable; privateintcount; privateICountService.StubserviceBinder=newICountService.Stub(){ @Override publicintgetCount()throwsRemoteException{ returncount; } }; @Override publicIBinderonBind(Intentintent){ returnserviceBinder; } @Override publicvoidonCreate(){ super.onCreate(); newThread(newRunnable(){ @Override publicvoidrun(){ while(! threadDisable){ try{ Thread.sleep(1000); }catch(InterruptedExceptione){ } count++; Log.v("CountService","Countis"+count); } } }).start(); } @Override publicvoidonDestroy(){ super.onDestroy(); this.threadDisable=true; Log.v("CountService","ondestroy"); } } 配置文件AndroidManifest.xml和上面的类似,没有区别。 在Activity中使用服务的差别不大,只需要对ServiceConnection中的调用远程服务的方法时,要捕获异常。 privateServiceConnectionserviceConnection=newServiceConnection(){ @Override publicvoidonServiceConnected(ComponentNamename,IBinderservice){ countService=(ICountService)service; try{ Log.v("CountService","onserivceconnected,countis" +countService.getCount()); }catch(RemoteExceptione){ thrownewRuntimeException(e); } } @Override publicvoidonServiceDisconnected(ComponentNamename){ countService=null; } }; 这样就可以在同一个应用程序中使用远程服务的方式和自己定义的服务交互了。 如果是另外的应用程序使用远程服务,需要做的是复制上面的aidl文件和相应的包构到应用程序中,其他调用等都一样。 编写传递复杂数据类型的远程服务 远程服务往往不只是传递java基本数据类型。 这时需要注意android的一些限制和规定: 1.android支持String和CharSequence 2.如果需要在aidl中使用其他aidl接口类型,需要import,即使是在相同包结构下; 3.android允许传递实现
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- android Service Binder交互通信实例 Binder 交互 通信 实例