Android开发之Service的远程调用
在Andorid平台中,各个组件运行在自己的进程中,他们之间是不能相互访问的,但是在程序之间是不可避免的要传递一些对象,在进程之间相互通信。为了实现进程之间的相互通信,Andorid采用了一种轻量级的实现方式RPC(Remote Procedure Call 远程进程调用)来完成进程之间的通信,并且Android通过接口定义语言(Andorid Interface Definition Language ,AIDL)来生成两个进程之间相互访问的代码,例如,你在Activity里的代码需要访问Service中的一个方法,那么就可以通过这种方式来实现了。
AIDL是Android的一种接口描述语言; 编译器可以通过aidl文件生成一段代码,通过预先定义的接口达到两个进程内部通信进程的目的. 如果需要在一个Activity中, 访问另一个Service中的某个对象, 需要先将对象转化成 AIDL可识别的参数(可能是多个参数), 然后使用AIDL来传递这些参数, 在消息的接收端, 使用这些参数组装成自己需要的对象。
AIDL RPC机制是通过接口来实现的,类似Windows中的COM或者Corba,但他是轻量级的,客户端和被调用实现之间是通过代理模式实现的,代理类和被代理类实现同一个接口Ibinder接口。
下面是实现Activity访问Service例子的步骤:
一.创建.aidl文件
AIDL使用简单的语法来声明接口,描述其方法以及方法的参数和返回值。这些参数和返回值可以是任何类型,甚至是其他AIDL生成的接口。重要的是必须导入导入除了内建类型(例如:int,boolean等)外的任何其他类型,哪怕是这些类型是在与接口相同的包中。具体的要求如下:
- JAVA基本数据类型不需要导入
- String,List,Map和CharSequence不需要导入
使用Eclipse的ADT插件创建一个BookInfo.aidl文件,该文件有4个方法:
setName(String name)设置图书的书名,setPrice(int price)设置图书的价格,setPublish(String pname)设置图书的出版社和String display()显示图书的信息.
BookInfo.aidl文件
- package com.android.aidl;
- //BookInfo接口
- interface BookInfo{
- void setName(String name);
- void setPrice(int price);
- void ssetPublish(String pname);
- //显示图书的信息
- String display();
- }
创建好BookInfo.aidl文件,系统会自动在gen目录下生成Java接口文件BookInfo.java

二.实现AIDL文件生成的JAVA接口
AIDL会生成一个和.aidl文件同名的JAVA接口文件,该接口中有一个静态抽象内部类Stub,该类中声明了AIDL文件中定义的所有方法,其中有一个重要的方法是asInterface(),该方法通过代理模式返回JAVA接口的实现我们可以定义一个实现类,BookImpl,该类继承Stub类,实现我们定义的4个方法
- package com.android.aidl;
- import android.os.RemoteException;
- public class BookInfoImpl extends BookInfo.Stub {
- //声明三个个变量
- private int price;
- private String name,pname;
- //显示书名,价格,出版社
- public String display() throws RemoteException{
- return "书名:"+name+";价格:"+price+";出版社:"+price;
- }
- @Override
- //设置书名
- public void setName(String name) throws RemoteException {
- // TODO Auto
- this.name= name;
- }
- @Override
- //设置价格
- public void setPrice(int price) throws RemoteException {
- // TODO Auto-generated method stub
- this.price = price;
- }
- @Override
- //设置出版社
- public void setPublish(String pname) throws RemoteException {
- // TODO Auto
- this.pname= pname;
- }
- }
三.向客户端暴露接口
现在已经实现了BookInfo接口,接下来要将该接口暴露给客户端调用。一般通过定义一个Service来实现,在Service的onBind()方法中返回该接口,当我们绑定该接口时调用该方法。
- package com.android.aidl;
- import com.android.aidl.BookInfo.Stub;
- import android.app.Service;
- import android.content.Intent;
- import android.os.IBinder;
- public class RemoteService extends Service {
- //声明BookInfo接口
- private Stub bookifo = new BookInfoImpl();
- public IBinder onBind(Intent intent){
- return bookifo;
- }
- }
四.在客户端调用
定义一个Activity来绑定远程Service,获得BookInfo接口,通过RPC机制调用接口中的方法。
- package com.android.aidl;
- import android.app.Activity;
- import android.app.Service;
- import android.content.ComponentName;
- import android.content.Intent;
- import android.content.ServiceConnection;
- import android.os.Bundle;
- import android.os.IBinder;
- import android.os.RemoteException;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends Activity {
- // 声明IPerson接口
- private BookInfo bookInfo;
- // 声明 Button
- private Button btn;
- // 实例化ServiceConnection
- private ServiceConnection conn = new ServiceConnection() {
- @Override
- synchronized public void onServiceConnected(ComponentName name, IBinder service) {
- // 获得IPerson接口
- bookInfo = BookInfo.Stub.asInterface(service);
- if (bookInfo != null)
- try {
- // RPC 方法调用
- bookInfo.setName("Google Android SDK开发范例大全");
- bookInfo.setPrice(55);
- bookInfo.setPublish("人民邮电出版社");
- String msg = bookInfo.display();
- // 显示方法调用返回值
- Toast.makeText(MainActivity.this, msg, Toast.LENGTH_LONG)
- .show();
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- @Override
- public void onServiceDisconnected(ComponentName name) {
- }
- };
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // 设置当前视图布局
- setContentView(R.layout.main);
- // 实例化Button
- btn = (Button) findViewById(R.id.Button1);
- //为Button添加单击事件监听器
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- // 实例化Intent
- Intent intent = new Intent();
- // 设置Intent Action 属性
- intent.setAction("com.android.aidl.action.MY_REMOTE_SERVICE");
- // 绑定服务
- bindService(intent, conn, Service.BIND_AUTO_CREATE);
- }
- });
- }
- }
五.main.xml和AndroidManifest.xml文件
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <Button
- android:text="远程调用Service"
- android:id="@+id/Button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
在AndroidManifest.xml文件16~20声明Service
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.aidl"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="10" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".MainActivity"
- 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="RemoteService">
- <intent-filter>
- <action android:name="com.android.aidl.action.MY_REMOTE_SERVICE"/>
- </intent-filter>
- </service>
- </application>
- </manifest>
效果图:

Android开发之Service的远程调用的更多相关文章
- android开发之service详解
service作为android的四大组件之一,其重要性可想而知,在开发中,我们经常把一些不需要与用户进行交互的工作放在service中来完成,service运行在后台,这样有些人可能会产生错觉,以为 ...
- Android开发之Service的写法以及与Activity的通信
Service的总结: 1.按运行地点分类: 类别 区别 优点 缺点 应用 本地服务(Local) 该服务依附在主进程上, 服务依附在主进程上而不是独立的进程,这样在一定程度上节约了资源,另外 ...
- Android开发之Service
什么是Service? Android中的服务与Activity不同,他是不能与用户进行交互,自己也不能启动在后台运行的程序,当我们退出应用时,Service应用并没有结束,它仍然在后台运行. 例子: ...
- Android开发之bindService()侦听service内部状态
在Android开发之bindService()通信的基础上,实现bindService()方法侦听service内部状态. 实现侦听service内部状态,使用的是回调机制 1.首先实现一个接口 p ...
- Android开发之旅: Intents和Intent Filters(理论部分)
引言 大部分移动设备平台上的应用程序都运行在他们自己的沙盒中.他们彼此之间互相隔离,并且严格限制应用程序与硬件和原始组件之间的交互. 我们知道交流是多么的重要,作为一个孤岛没有交流的东西,一定毫无意义 ...
- Android开发之Java必备基础
Android开发之Java必备基础 Java类型系统 Java语言基础数据类型有两种:对象和基本类型(Primitives).Java通过强制使用静态类型来确保类型安全,要求每个变量在使用之前必须先 ...
- [置顶] Android开发之MediaPlayerService服务详解(一)
前面一节我们分析了Binder通信相关的两个重要类:ProcessState 和 IPCThreadState.ProcessState负责打开Binder 驱动,每个进程只有一个.而 IPCThre ...
- [置顶] Android开发之serviceManager分析
Android 开发之serviceManager分析 在Android系统中用到最多的通信机制就是Binder,Binder主要由Client.Server.ServiceManager和Binde ...
- Android开发之TextView高级应用
Android开发之TextView高级应用 我们平时使用TextView往往让它作为一个显示文字的容器,但TextView的功能并不局限于此.以下就和大家分享一下TextView的一些使用技巧. A ...
随机推荐
- Substring with Concatenation of All Words leetcode java
题目: You are given a string, S, and a list of words, L, that are all of the same length. Find all sta ...
- 亚马逊AWS免费套餐EC2安装centos连接登录并创建root
前言:刚开始使用亚马逊的AWS的免费套餐EC2,由于个人习惯使用centos系统,所以果断安装,但是AWS为了安全性,默认禁止用户使用root账户,导致安装配置环境各种问题.所以我把从安好系统后遇到的 ...
- 错误: 找不到或无法加载主类 Files\red5-server ,原因与解决办法
因为你把 red5放到了 Program Files 下,而Program Files 中间有个空格,启动路径不允许有空格,换个没空格的路径就OK啦
- IOS Xib使用——Xib表示局部界面
Xib文件是一个轻量级的用来描述局部界面的文件,在之前的文章讲解了为控制器添加Xib文件,本节主要讲解一下通过xib文件表示局部界面. <一> 创建Xib文件 Xib文件创建的时候是选择U ...
- 《TCP/IP具体解释卷2:实现》笔记--接口层
接口层包含在本地网上发送和接收分组的硬件与软件. 我们用设备驱动程序来表示与硬件及网络接口通信的软件,网络接口是指在一个特定网络上硬件与设备驱动器之间的接口. Net/3接口层试图在网络协议和连接到一 ...
- Callable、Future&阻塞队列&阻塞栈
Callable.Future 简单应用 在Java5之前,线程是没有返回值的,常常为了“有”返回值,破费周折,而且代码很不好写.或者干脆绕过这道坎,走别的路了.现在Java终于有可返回值的任务( ...
- Android -- 点击双下返回退出程序
背景 现在好多apk ...
- 我为何放弃Gulp与Grunt,转投npm scripts(上)
本文来源于我在InfoQ中文站翻译的文章.原文地址是:http://www.infoq.com/cn/news/2016/02/gulp-grunt-npm-scripts-part1 Cory Ho ...
- 【UI设计】扁平化设计之流行色值
收集了一些颜色值 顏色表示方法: 以命名方式定义经常使用的顏色,如color="green".可是自由度较低,何况单词量...... 以RGB值表示.如#FF0000表示red(红 ...
- DB2数据源在Spring环境中的配置
简单记录一下,以备不时之需. DB2的java驱动包可以在这里下载:http://pan.baidu.com/s/1gOoEJ DB2数据源的配置如下,粗体字部分是需要根据实际情况修改的: <b ...