在android开发过程中,为了让其他的应用程序,也可以访问本应用程序的服务,android系统采用远程过程调用来实现。android通过接口来公开定义的服务。我们将能够夸进程访问的服务成为AIDL服务(Android Interface Definition Language)。本节主要讲述通过aidl服务来传递数据。aidl支持的数据类型“简单数据类型、String和char、List和Map、aidl自动生成的接口、实现android.Parcelable的类。

1.建立aidl服务

在Eclipse中建立android_adil应用程序,在java的包目录中建立一个IMyService.aidl文件.

 package com.example.android_demo_aidl;
import com.example.android_demo_aidl.Person;
interface IMyService
{
Map getMap(in String key,in Person person);
Person getPerson();
}

IMyService.aidl

Person是实现了parcelable接口的类,需要使用import导入。in表示该值可以在客户端设置,out表示该值可以在服务端设置,inout表示该值既可以在客户端设置,也可以再服务端设置。如果aidl正确,会自动生成IMyService.java文件。

在包中建立Person类。

 package com.example.android_demo_aidl;

 import android.os.Parcel;
import android.os.Parcelable; public class Person implements Parcelable { private int id;
private String name;
private int age;
public static final Parcelable.Creator<Person> CREATOR= new Parcelable.Creator<Person>() { @Override
public Person[] newArray(int size) {
// TODO Auto-generated method stub
return new Person[size];
} @Override
public Person createFromParcel(Parcel source) {
// TODO Auto-generated method stub
return new Person(source);
}
};
public Person()
{
}
private Person(Parcel in)
{
readFormParce(in);
}
private void readFormParce(Parcel in) {
// TODO Auto-generated method stub
id=in.readInt();
name=in.readString();
age=in.readInt(); }
public int describeContents()
{
return 0;
}
public void writeToParcel(Parcel dest,int flags)
{
dest.writeInt(id);
dest.writeString(name);
dest.writeInt(age);
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id=id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name=name;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age=age;
}
}

Person

Person类定义name,age等成员变量,实现了接口parcelable。同时必须定义CREATOR的常量,类型为Parcelable.Creator。在writeToParcel中将序列化的值传入Parcel。

建立Person.aidl

parcelable Person;

编写MyService类

 package com.example.android_demo_aidl;

 import java.util.HashMap;
import java.util.Map; import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log; public class MyService extends Service { public class MyServiceImpl extends IMyService.Stub
{ @Override
public Map getMap(String key, Person person) throws RemoteException {
// TODO Auto-generated method stub
Map map = new HashMap<String,String>();
map.put("id", person.getId());
map.put("age", person.getAge());
map.put("name", person.getName());
map.put("person", person);
return map;
} @Override
public Person getPerson() throws RemoteException {
// TODO Auto-generated method stub
Person person = new Person();
person.setAge(18);
person.setId(1);
person.setName("Tom");
return person;
} }
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return new MyServiceImpl();
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.d("test", "oncreate");
}
}

MyService

在MyService类中定义一个新类MyServiceIm继承于IMyService.Stub.需要实现在接口中定义的方法。MyService类继承android.Service,在绑定方法中,返回一个实例。

最后,在AndroidManifest.xml中配置该服务。

         <service android:name=".MyService">
<intent-filter >
<action android:name="com.example.android_demo_aidl.IMyService"/>
</intent-filter>
</service>

AndroidManifest.xml

android:name,在客户端通过该id调用服务。

2.调用服务

在Eclipse中建立新的android应用程序,android_ail_client。在调用服务之前,需要绑定服务,通过bindService进行服务的绑定。将服务端自动生成的IMyservice.java连同包一起复制到新的应用程序用。程序结构如下图

 package com.example.android_demo_aidl_client;

 import com.example.android_demo_aidl.IMyService;

 import android.support.v7.app.ActionBarActivity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView; public class MainActivity extends ActionBarActivity implements OnClickListener { private Button btnstart;
private Button btninvoke;
private IMyService myService=null;
private TextView textView;
private ServiceConnection conn=new ServiceConnection() { @Override
public void onServiceDisconnected(ComponentName name) {
// TODO Auto-generated method stub
Log.d("test", "绑定错误");
} @Override
public void onServiceConnected(ComponentName name, IBinder service) {
// TODO Auto-generated method stub
myService=IMyService.Stub.asInterface(service);
btninvoke.setEnabled(true);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnstart=(Button)findViewById(R.id.button1);
btninvoke=(Button)findViewById(R.id.button2);
textView=(TextView)findViewById(R.id.textView1); btninvoke.setOnClickListener(this);
btnstart.setOnClickListener(this);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.button1:
bindService(new Intent("com.example.android_demo_aidl.IMyService"), conn, Context.BIND_AUTO_CREATE);
break;
case R.id.button2:
try
{
String s="";
s="person.id="+myService.getPerson().getId()+"\n";
s+="person.name="+myService.getPerson().getName()+"\n";
s+="person.age="+myService.getPerson().getAge();
textView.setText(s);
}
catch(Exception e)
{
Log.d("test",e.getMessage());
}
break;
}
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unbindService(conn);
}
}

MainActivity

在该段代码中,通过ServiceConnection获取Aidl服务的对象实例。在调用服务之前需先绑定服务。

3.程序运行截图

运行的时候,需要先运行服务端程序,再运行客户端程序。

Android服务之AIDL的更多相关文章

  1. Android服务Service具体解释(作用,生命周期,AIDL)系列文章-为什么须要服务呢?

    Android服务Service具体解释(作用,生命周期,AIDL) 近期沉迷于上班,没有时间写博客了.解衣入睡,未眠.随起床写一篇博客压压惊! ##我们android系统为什么须要服务Service ...

  2. Android探索之AIDL实现进程间通信

    前言: 前面总结了程序间共享数据,可以使用ContentProvider也可以使用SharedPreference,那么进程间怎么共享内存呢?Android系统中的进程之间不能共享内存,因此,需要提供 ...

  3. Android服务(Service)研究

    Service是android四大组件之一,没有用户界面,一直在后台运行. 为什么使用Service启动新线程执行耗时任务,而不直接在Activity中启动一个子线程处理? 1.Activity会被用 ...

  4. Android 中的AIDL,Parcelable和远程服务

    Android 中的AIDL,Parcelable和远程服务      早期在学习期间便接触到AIDL,当时对此的运用也是一撇而过.只到近日在项目中接触到AIDL,才开始仔细深入.AIDL的作用    ...

  5. Android 服务类Service 的详细学习

    http://blog.csdn.net/vipzjyno1/article/details/26004831 Android服务类Service学习四大组建   目录(?)[+] 什么是服务 服务有 ...

  6. Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  7. Android开发了解——AIDL

    AIDL:Android Interface Definition Language,即Android接口定义语言. 什么是AIDL Android系统中的进程之间不能共享内存,因此,需要提供一些机制 ...

  8. (转载)Android:学习AIDL,这一篇文章就够了(下)

    前言 上一篇博文介绍了关于AIDL是什么,为什么我们需要AIDL,AIDL的语法以及如何使用AIDL等方面的知识,这一篇博文将顺着上一篇的思路往下走,接着介绍关于AIDL的一些更加深入的知识.强烈建议 ...

  9. (转载)Android:学习AIDL,这一篇文章就够了(上)

    前言 在决定用这个标题之前甚是忐忑,主要是担心自己对AIDL的理解不够深入,到时候大家看了之后说——你这是什么玩意儿,就这么点东西就敢说够了?简直是坐井观天不知所谓——那样就很尴尬了.不过又转念一想, ...

随机推荐

  1. Html5移动端页面布局通用模板暨移动端问题总结

    最近的移动端项目终于告一段落了,其中遇到了不少问题,在此和大家总结分享. 首先,说一下结构.一般的手机页面大致可以分为五块:head, content, foot,solidbar,dialog. 针 ...

  2. select选项改变时获取选中的option的值

    本来天真的以为直接this.value()就能去到select的值,可事实并非那么回事. <script> document.getElementById('select').onchan ...

  3. Mysql操作个人收集

    1.MySQL修改root密码 mysql> UPDATE user SET Password=PASSWORD('xxxx') where USER='root'; mysql> FLU ...

  4. git操作流程

  5. jquery.ajax和Ajax 获取数据

    前几天接触了jquery 看到里面ajax的部分,自己也不是很懂,然后有重复看了即便,然后写了一个小功能,分享下...我刚学的.有错误的请指教. 验证用户名是否存在 在checkname_jqajax ...

  6. JavaScript开发规范

    作为一名开发人员(WEB前端JavaScript开发),不规范的开发不仅使日后代码维护变的困难,同时也不利于团队的合作,通常还会带来代码安全以 及执行效率上的问题.本人在开发工作中就曾与不按规范来开发 ...

  7. 基于cygwin构建u-boot(一)环境搭建

    从本文开始,更系统的描述基于cygwin构建u-boot. 之前<痛苦的版本对齐>系列,对于cygwin环境下Sourcery CodeBench,u-boot-1.1.6的构建有侧面的说 ...

  8. c++基础五个题(二)

    一.c++中static的作用 1.隐藏:当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性,static函数作用就是为了隐藏 2.可以保持变量的持久:存储在静态数据区的变 ...

  9. T-SQL 运算符

    运算符 1.算术运算符 算术运算符 说明 + 加法 - 减法 * 乘法 / 除法 % 取模,两个整数相除后的余数 2.位运算符 位运算符 说明 &(与.and) 按位逻辑与运算 |(或.OR) ...

  10. 互斥体与互锁 <第五篇>

    互斥体实现了“互相排斥”(mutual exclusion)同步的简单形式(所以名为互斥体(mutex)).互斥体禁止多个线程同时进入受保护的代码“临界区”.因此,在任意时刻,只有一个线程被允许进入这 ...