编程回忆之Android回忆(AIDL的使用)

AIDL技术详解与实现流程
本文详细介绍了AIDL(Android Interface Definition Language)的概念、作用、实现过程以及服务端和客户端的实现方法,通过示例代码展示了如何在Android应用中使用AIDL进行进程间通信。

AIDL的使用

AIDL:Android Interface Definition Language,即Android接口定义语言。

一、什么是AIDL

Android系统中的进程之间不能共享内存,因此,需要提供一些机制在不同进程之间进行数据通信。
为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现。与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口。我们知道4个Android应用程序组件中的3个(Activity、BroadcastReceiver和ContentProvider)都可以进行跨进程访问,另外一个Android应用程序组件Service同样可以。因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Language)服务。

二、AIDL通信机制

AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码,实现Android设备上的两个进程间通信(IPC)。AIDL的IPC机制和EJB所采用的CORBA很类似,进程之间的通信信息,首先会被转换成AIDL协议消息,然后发送给对方,对方收到AIDL协议消息后再转换成相应的对象。由于进程之间的通信信息需要双向转换,所以android采用代理类在背后实现了信息的双向转换,代理类由android编译器生成,对开发人员来说是透明的。

三、ALDL实现过程

假设A应用需要与B应用进行通信,调用B应用中的download(String path)方法,B应用以Service方式向A应用提供服务。需要下四个步骤

1、在B应用中创建*.aidl文件。

2、在B应用中实现aidl文件生成的接口。

3、在B应用中创建一个Service(服务)。

4、把B应用中aidl文件所在package连同aidl文件一起拷贝到客户端A应用。

四、AIDL服务端

建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:
(1)在Eclipse Android工程的Java包目录中建立一个扩展名为aidl的文件。该文件的语法类似于Java代码,但会稍有不同。
(2)如果aidl文件的内容是正确的,ADT会自动生成一个Java接口文件(*.java)。
(3)建立一个服务类(Service的子类)。
(4)实现由aidl文件生成的Java接口。
(5)在AndroidManifest.xml文件中配置AIDL服务,尤其要注意的是,<action>标签中android:name的属性值就是客户端要引用该服务的ID,也就是Intent类的参数值。
代码结构图:
 aidl文件:
package com.lyh.aidltest.prt;

interface IGetMsg{
	String getMsg();
}
aidl文件的实现:
public class MsgBinder extends Stub {

		@Override
		public String getMsg() throws RemoteException {
			// TODO Auto-generated method stub
			return "连接上了!!!!";
		}
	}
AndroidManifest.xml文件配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lyh.aidltest"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.lyh.aidltest.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=".GetMsgService">
            <intent-filter >
                <action android:name="cn.bgxt.Service.BASE_TYPE_SERVICE"/>
            </intent-filter>
            
        </service>
    </application>

</manifest>

五、aidl客户端的实现

我们只需要把aidl文件拷到相应的目录中即可,编译器同样会生成相对应的IPerson.java文件,这一部分和服务端没什么区别。这样一来,服务端和客户端就在通信协议上达到了统一。我们主要工作在MainActivity中完成。

代码结构图:


MainActivity代码:

package com.lyh.aidlclienttest;

import com.lyh.aidltest.prt.IGetMsg;

import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity implements OnClickListener{
	private Button getmsg;
	private IGetMsg getmsgService;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		startService();
		getmsg=(Button) findViewById(R.id.getmsg);
		getmsg.setOnClickListener(this);
	}

	@Override
	public void onClick(View arg0) {
		// TODO Auto-generated method stub
		if(getmsgService!=null){
			try {
				Toast.makeText(MainActivity.this, getmsgService.getMsg(), Toast.LENGTH_SHORT).show();
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	
private ServiceConnection connBase=new ServiceConnection() {
		
		@Override
		public void onServiceDisconnected(ComponentName name) {
			getmsgService=null;
		}
		
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// IDog.Stub.asInterface,获取接口
			getmsgService=IGetMsg.Stub.asInterface(service);
		}
	};
	
	/**
	 * 开始服务
	 */
	private void startService(){
		Intent intent=new Intent();
		intent.setAction("cn.bgxt.Service.BASE_TYPE_SERVICE");
		bindService(intent, connBase, BIND_AUTO_CREATE);
		Toast.makeText(MainActivity.this, "开始绑定服务", Toast.LENGTH_SHORT).show();
	}
	/**
	 * 停止服务
	 */
	private void endService(){
		if(connBase!=null)
		{
			unbindService(connBase);
			Toast.makeText(MainActivity.this, "服务解除绑定", Toast.LENGTH_SHORT).show();
		}
	}

	/* (non-Javadoc)
	 * @see android.app.Activity#onDestroy()
	 */
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		endService();
		super.onDestroy();
	}
	
}


备注:测试时记得先启动服务端,再启动客户端!!

 

测试源码地址:http://download.youkuaiyun.com/detail/stop_pig/7065721


 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值