服务(Service)是Android的四大组件之一,它利用底层Binder机制,实现了RPC机制。 一个服务即可以存在于一个独立的进程,也可以依附于已存在的某个进程中。服务可被同一进程中的Activity调用,也可以被位于不同进程中的某个Activity调用。 本文主要探讨怎样编写一个远程服务接口的过程。为演示作用,本文不介绍通过AIDL语言自动生成服务接口代码的过程。

首先,我们定义接口:

public interface IRemoteService extends IInterface {/***  serviceMethod*/public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) throws RemoteException;}

需要说明的是,由于受Binder机制的约束,除基本数据类型外,对于自定义的数据类型,必须实现Parceable接口,才能作为服务方法的参数。本文将不考虑自定义类型作为参数传递的情况。

接下来的重点就是实现上述定义的服务接口,这里,为了支持同一进程和不同进程的Activity都能够调用该服务接口,我们需要两个接口实现,一个是本地实现,一个是远程实现。在介绍这两个实现代码之前,我们先看下对应的RemoteService类的实现:

public RemoteService extends Service {@Overridepublic void onCreate() {}@Overridepublic void onDestroy() {}@Overridepublic IBinder onBind(Intent intent) {// Select the interface to return.  If your service only implements// a single interface, you can just return it here without checking// the Intent.if (IRemoteService.class.getName().equals(intent.getAction())) {return mBinder;}return null;}/*** The IRemoteInterface is defined through IDL*/private final RemoteServiceStub mBinder = new RemoteServiceStub() {public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) {//do something here}};
}

在Android App开发中,定义自己的服务需要从Service类中派生,启动一个Service可以通过startService,也可以通过bindService, 对于通过bindService调用一个服务接口的方式,同时需要实现onBind()方法,它返回的IBinder对应就是我们下面将要介绍的服务实现类。

首先是本地接口实现类,代码如下:

/** Local-side IPC implementation stub class. */
public abstract class RemoteServiceStub extends Binder implements   IRemoteService {private static final String DESCRIPTOR = "com.fyj.test.IRemoteService";/** Construct the stub at attach it to the interface. */public RemoteServiceStub() {this.attachInterface(this, DESCRIPTOR);}/*** Cast an IBinder object into an* com.fyj.test.IRemoteService interface, generating a* proxy if needed.*/public static IRemoteService asInterface(IBinder obj) {if ((obj == null)) {return null;}IInterface iin = (android.os.IInterface) obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof IRemoteService))) {return ((IRemoteService) iin);}return new RemoteServiceProxy(obj);}public IBinder asBinder() {return this;}@Overridepublic boolean onTransact(int code, Parcel data, Parcel reply, int flags)throws RemoteException {switch (code) {case INTERFACE_TRANSACTION: {reply.writeString(DESCRIPTOR);return true;}case TRANSACTION_methodService: {data.enforceInterface(DESCRIPTOR);int _arg0;_arg0 = data.readInt();float _arg1;_arg1 = data.readFloat();long _arg2;_arg2 = (0!=data.readLong());boolean _arg3;_arg3 = data.readInt()?true:false;double _arg4;_arg4 = data.readDouble();String _arg5;_arg5 = data.readString();this.serviceMethod(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5);reply.writeNoException();return true;}}return super.onTransact(code, data, reply, flags);}public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) throws RemoteException;static final int TRANSACTION_methodService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

它实现为一个抽象类,将接口的具体实现延迟到RemoteService中去实现。在本类 中,主要实现了onTransact()方法,它将处理客户的调用请求。asInterface()接口将自动判断当前是本地调用还是远程调用,如果是远程调用,将使用 RemoteServiceProxy类的实例的接口调用服务,它的实现代码如下:

/** Local-side IPC implementation stub class. */
public class RemoteServiceProxy implements IRemoteService {private static final String DESCRIPTOR = "com.fyj.test.IRemoteService";private IBinder mRemote;RemoteServiceProxy(IBinder remote) {mRemote = remote;}public IBinder asBinder() {return mRemote;}public String getInterfaceDescriptor() {return DESCRIPTOR;}public void serviceMethod(int arg0, float arg1, long arg2, boolean arg3, double arg4, String arg5) throws RemoteException{Parcel _data = Parcel.obtain();Parcel _reply = Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);_data.writeInt(anInt);_data.writeFloat(aFloat);_data.writeLong(aLong);_data.writeInt(((aBoolean)?(1):(0)));_data.writeDouble(aDouble);_data.writeString(aString);mRemote.transact(TRANSACTION_methodService, _data, _reply, 0);_reply.readException();}finally {_reply.recycle();_data.recycle();}}static final int TRANSACTION_methodService = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}

该类是代理类,对服务的调用者是透明的。

在调用bindService的过程中,需要传递一个ServiceConnection对象,该对象将在服务连接成功后,会接收到服务类的对象,以此可以判断当前应该使用本地服务类实现,还是远程服务类实现,关于具体的实现细节,将另外专题分析。 下面给出ServiceConnection对象实现创建的代码:

private ServiceConnection mConnection = new ServiceConnection() {public void onServiceConnected(ComponentName className, IBinder service) {// TODO Auto-generated method stubmService = RemoteServiceStub.asInterface(service);...}public void onServiceDisconnected(ComponentName className) {// TODO Auto-generated method stubmService = null;...}};

转载于:https://my.oschina.net/fuyajun1983cn/blog/263932

编写android服务相关推荐

  1. android从服务端获取json解析显示在客户端上面,Android服务端获取json解析显示在客户端上面.doc...

    Android服务端获取json解析显示在客户端上面 Android从服务端获取json解析显示在客户端上面 首先说一下Json数据的最基本的特点,Json数据是一系列的键值对的集合,和XML数据来比 ...

  2. python开发安卓程序-python可以编写android程序吗?

    python可以编写android程序吗?答案是肯定的.Android不直接支持使用python开发应用,需要使用其它中间件或者库.PythonForAndroid.CLE以及Wrapandroid ...

  3. 【转】独家教程:用PHP编写Android应用程序

    Google的开源Android移动操作系统正在席卷全球智能手机市场,和苹果不一样,它对那些想将应用程序提交到iPhone App Store的开发人员有着严格的指导方针和要求,Google的Andr ...

  4. python可以写安卓应用吗_python可以编写android程序吗?

    python可以编写android程序吗?答案是肯定的.Android不直接支持使用python开发应用,需要使用其它中间件或者库.PythonForAndroid.CLE以及Wrapandroid ...

  5. erlang-百度云推送Android服务端功能实现-erlang

    百度云推送官方地址http://developer.baidu.com/wiki/index.php?title=docs/cplat/push 简单的介绍下原理: 百度云推送支持IOS和Androi ...

  6. Android服务一 创建启动服务

    若要学习创建绑定服务,请查看下篇Android服务二 创建绑定服务 启动服务 基于Service package service;import android.app.Service; import ...

  7. Qt创建Android服务

    Qt创建Android服务 创建Android服务 创建Android服务 从Qt 5.7开始,您可以使用Qt创建Android服务.服务是在后台运行的组件,因此它没有用户界面.执行长期操作(例如记录 ...

  8. Android 服务入门

    前言:硬着头皮把数据库SQLite看完了,接下来就是android服务了,因为自己本身就是菜鸟,所以呢,也只是做做笔记,技术上的东西就别指望我了. 1.什么是服务呢?举个例子,百度地图,美团外卖,OF ...

  9. android.os.binderproxy cannot be cast to,Android服务android.os.BinderProxy错误

    我一直在尝试使此android服务正常工作,但我不知道为什么会收到此错误. 05-13 12:13:36.203: ERROR/dalvikvm(7782): could not disable co ...

最新文章

  1. 马斯克Neuralink被曝“虐杀实验猴”,140万元美金项目遭谴责
  2. hashcode、equals和==简单总结
  3. sql查询远程数据库的表的数据并填充到本地数据库的表
  4. 登录状态保持Session/Cookie
  5. CentOS 7.0服务器安装配置LAMP服务器
  6. 剑指offer 用2个栈实现队列
  7. sklearn自学指南(part55)--决策树
  8. php declare 作用,php declare用法详解
  9. 代码审计之SQL注入:BlueCMSv1.6 sp1
  10. android include 点击事件,Android编程之include文件的使用方法
  11. 防火墙阻止网页连接网络连接_win7电脑打不开网页怎么办 win7电脑打不开网页解决步骤【图文步骤】...
  12. 【ElasticSearch】es ResourceWatcherService 的 初始化 启动 源码解析
  13. linux下串口抓包,Linux的串行端口 - wrtie()字节到目标设备通过串口
  14. 解决Fedora中root无法登录问题
  15. 贾跃亭发布最新PPT:FF商业计划书
  16. Oracle锁表会影响查询效率么,oracle锁表查询,资源占用,连接会话,低效SQL等性能检查...
  17. Java美颜相机(1)图像处理
  18. Java环境变量配置cobalt strick4.4启动
  19. [云计算] 云使能技术包括哪些技术组件?
  20. 对arr与arr的理解

热门文章

  1. java数据结构-HashMap
  2. Redis介绍使用及进阶
  3. 线性表----单链表
  4. [转载]项目风险管理七种武器-孔雀翎
  5. centso7 install Mariadb
  6. 读书笔记:《思考的乐趣:Matrix67数学笔记》第4章 统计数据的陷阱
  7. CentOS6.0_X86_64 oracle 11g R2 开机自动启动(linux)
  8. linux shell 去掉 文本换行符
  9. 数据库 sqlite order by对结果集进行排序
  10. linux 单用户模式 救援模式 忘记root密码的两种解决办法