android Service Binder交互通信实例.docx

上传人:b****6 文档编号:8117486 上传时间:2023-01-28 格式:DOCX 页数:16 大小:18.19KB
下载 相关 举报
android Service Binder交互通信实例.docx_第1页
第1页 / 共16页
android Service Binder交互通信实例.docx_第2页
第2页 / 共16页
android Service Binder交互通信实例.docx_第3页
第3页 / 共16页
android Service Binder交互通信实例.docx_第4页
第4页 / 共16页
android Service Binder交互通信实例.docx_第5页
第5页 / 共16页
点击查看更多>>
下载资源
资源描述

android Service Binder交互通信实例.docx

《android Service Binder交互通信实例.docx》由会员分享,可在线阅读,更多相关《android Service Binder交互通信实例.docx(16页珍藏版)》请在冰豆网上搜索。

android Service Binder交互通信实例.docx

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允许传递实现

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 工学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1