本地服务和远程服务AIDL
来源:互联网 发布:淘宝网上禁止出售滥用 编辑:程序博客网 时间:2024/04/27 18:42
AIDL IPC机制是面向接口的,它是使用代理类(stub)在客户端和实现端传递数据。
在Android中,每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢?显然,Java中是不支持跨进程内存共享的,因此要传递对象,需要把对象解析成操作系统能够理解的数据格式,以达到跨界对象访问的目的。在Android中,则采用AIDL(Android Interface Definition Language :接口定义语言)方式实现。
编写不需和Activity交互的本地服务示例
本地服务编写比较简单。首先,要创建一个Service类,该类继承android的Service类。这里写了一个计数服务的类,每秒钟为计数器加一。在服务类的内部,还创建了一个线程,用于实现后台执行上述业务逻辑。
package com.easymorse;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.util.Log;public class CountService extends Service { private boolean threadDisable; private int count; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); new Thread(new Runnable() { @Override public void run() { while (!threadDisable) { try { Thread.sleep(1000); } catch (InterruptedException e) { } count++; Log.v("CountService", "Count is " + count); } } }).start(); } @Override public void onDestroy() { super.onDestroy(); this.threadDisable = true; Log.v("CountService", "on destroy"); } public int getCount() { return count; }}需要将该服务注册到配置文件AndroidManifest.xml中,否则无法找到:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.easymorse" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".LocalServiceDemoActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="CountService" /> </application> <uses-sdk android:minSdkVersion="3" /></manifest>在Activity中启动和关闭本地服务。
package com.easymorse;import android.app.Activity;import android.content.Intent;import android.os.Bundle;public class LocalServiceDemoActivity extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.startService(new Intent(this, CountService.class)); } @Override protected void onDestroy() { super.onDestroy(); this.stopService(new Intent(this, CountService.class)); }}
可通过日志查看到后台线程打印的计数内容。
编写本地服务和Activity交互的示例
上面的示例是通过startService和stopService启动关闭服务的。适用于服务和activity之间没有调用交互的情况。如果之间需要传递参数或者方法调用。需要使用bind和unbind方法。
具体做法是,服务类需要增加接口,比如ICountService,另外,服务类需要有一个内部类,这样可以方便访问外部类的封装数据,这个内部类需要继承Binder类并实现ICountService接口。还有,就是要实现Service的onBind方法,不能只传回一个null了。
这是新建立的接口代码:
package com.easymorse;public interface ICountService { public abstract int getCount();}修改后的CountService代码:
package com.easymorse;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class CountService extends Service implements ICountService { private boolean threadDisable; private int count; private ServiceBinder serviceBinder=new ServiceBinder(); public class ServiceBinder extends Binder implements ICountService{ @Override public int getCount() { return count; } } @Override public IBinder onBind(Intent intent) { return serviceBinder; } @Override public void onCreate() { super.onCreate(); new Thread(new Runnable() { @Override public void run() { while (!threadDisable) { try { Thread.sleep(1000); } catch (InterruptedException e) { } count++; Log.v("CountService", "Count is " + count); } } }).start(); } @Override public void onDestroy() { super.onDestroy(); this.threadDisable = true; Log.v("CountService", "on destroy"); } /* (non-Javadoc) * @see com.easymorse.ICountService#getCount() */ public int getCount() { return count; }}
服务的注册也要做改动,AndroidManifest.xml文件:
<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.easymorse" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".LocalServiceDemoActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="CountService"> <intent-filter> <action android:name="com.easymorse.CountService"/> </intent-filter> </service> </application> <uses-sdk android:minSdkVersion="3" /></manifest>
Acitity代码不再通过startSerivce和stopService启动关闭服务,另外,需要通过ServiceConnection的内部类实现来连接Service和Activity。
package com.easymorse;import android.app.Activity;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.util.Log;public class LocalServiceDemoActivity extends Activity { private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { countService = (ICountService) service; Log.v("CountService", "on serivce connected, count is " + countService.getCount()); } @Override public void onServiceDisconnected(ComponentName name) { countService = null; } }; private ICountService countService; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.bindService(new Intent("com.easymorse.CountService"), this.serviceConnection, BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); this.unbindService(serviceConnection); }}
编写传递基本型数据的远程服务
上面的示例,可以扩展为,让其他应用程序复用该服务。这样的服务叫远程(remote)服务,实际上是进程间通信(RPC)。
这时需要使用android接口描述语言(AIDL)来定义远程服务的接口,而不是上述那样简单的java接口。扩展名为aidl而不是java。可用上面的ICountService改动而成ICountSerivde.aidl,eclipse会自动生成相关的java文件。
package com.easymorse;interface ICountService { int getCount();}
编写服务(Service)类,稍有差别,主要在binder是通过远程获得的,需要通过桩(Stub)来获取。桩对象是远程对象的本地代理。
package com.easymorse;import android.app.Service;import android.content.Intent;import android.os.IBinder;import android.os.RemoteException;import android.util.Log;public class CountService extends Service { private boolean threadDisable; private int count; private ICountService.Stub serviceBinder = new ICountService.Stub() { @Override public int getCount() throws RemoteException { return count; } }; @Override public IBinder onBind(Intent intent) { return serviceBinder; } @Override public void onCreate() { super.onCreate(); new Thread(new Runnable() { @Override public void run() { while (!threadDisable) { try { Thread.sleep(1000); } catch (InterruptedException e) { } count++; Log.v("CountService", "Count is " + count); } } }).start(); } @Override public void onDestroy() { super.onDestroy(); this.threadDisable = true; Log.v("CountService", "on destroy"); }}
配置文件AndroidManifest.xml和上面的类似,没有区别。
在Activity中使用服务的差别不大,只需要对ServiceConnection中的调用远程服务的方法时,要捕获异常。
private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { countService = (ICountService) service; try { Log.v("CountService", "on serivce connected, count is " + countService.getCount()); } catch (RemoteException e) { throw new RuntimeException(e); } } @Override public void onServiceDisconnected(ComponentName name) { countService = null; }};
这样就可以在同一个应用程序中使用远程服务的方式和自己定义的服务交互了。
如果是另外的应用程序使用远程服务,需要做的是复制上面的aidl文件和相应的包构到应用程序中,其他调用等都一样。
- 本地服务和远程服务AIDL
- 安卓中本地服务Service和远程服务AIDL的使用
- android应用层服务——binderService,StartService,aidl,本地服务和远程服务
- AIDL, Parcelable和远程服务
- 关于service:本地服务 与 远程服务AIDL
- aidl远程服务调用
- AIDL绑定远程服务
- aidl绑定远程服务
- Service (aidl远程服务)
- AIDL实现远程服务
- Android 中的AIDL,Parcelable和远程服务
- Android AIDL, Parcelable和远程服务
- android本地服务和远程服务
- 安卓 本地服务和远程服务
- Android中的本地服务、远程服务和系统服务
- 采用aidl绑定远程服务
- Android AIDL实现远程服务
- 采用AIDL调用远程服务
- Linux netfilter 学习笔记 之十一 ip层netfilter的NAT模块初始化以及NAT原理
- 用CornerStone配置SVN,HTTP及svn简单使用说明
- SVNcheck下来的项目转换为maven项目。
- css使宽度不定的div水平居中
- NDK 与 JNI 的关系
- 本地服务和远程服务AIDL
- 应用之星荣获2014全球移动互联网卓越成就奖
- SRP(Secure Remote Protocol)资料
- 深入理解JVM内幕:从基本结构到Java 7新特性
- CSS的优先级总结
- jQuery获取各种html标签的值
- Hduoj1698【线段树】
- Win7中IIS出现“HTTP 错误 404.17 - Not Found 请求的内容似乎是脚本,因而将无法由静态文件处理程序来处理。
- 利用vs2010的属性表自动配置OpenCV