AIDL的使用

本文详细介绍AIDL在Android中的应用,通过实例演示了如何搭建远程服务并实现跨进程调用。从创建服务端到客户端的绑定和服务方法调用,再到AIDL文件的作用及生成机制,一步步解析AIDL的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

aidl可用于进程间的通讯,我们都知道一个安卓应用程序对应一个虚拟机,原则上是不允许不同的虚拟机之间通信的,这时候就出来远程服务aidl它可以进行不同进程间的通讯。

aidl它其实是一种语言IPC,是通过binder实现的(具体原理下一篇中讲解)

下面我们来看一个晓得例子:
新建一个项目起名为远程服务:
RemoteService:
这里写图片描述

这个远程服务要被另外一个项目调用:

第一步创建一个远程服务RemoteService集成Service代码如下:

package com.example.aidl;

import com.example.aidl.invoke.IService;
import com.example.aidl.invoke.IService.Stub;

import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;

/**
 * 远程服务
 * @author Administrator
 *
 */
public class RemoteService extends Service {

    @Override
    public IBinder onBind(Intent arg0) {
        return new MyBinder();
    }

    // 业务逻辑方法
    public void serviceMethod(){
        System.out.println("*************************");
    }


    //  创建一个供外部调用逻辑的中间类
    private class MyBinder extends Stub{

        @Override
        public void callMethod() {
            //调用服务的业务逻辑方法
            serviceMethod();
        }

    }

}

上面代码中中间类刚开始是继承IService的,刚开始是创建的IService是一个接口扩展名是Java的,如下:

package com.example.aidl.invoke;

/**
 * 供外面调用的接口
 * @author Administrator
 *
 */
 interface IService {

    /**
     * 供外面操作调用的方法
     */
    void callMethod();

}

然后再远程项目中测试一下服务,看是否好使,代码如下:

package com.example.aidl;

import com.example.aidl.invoke.IService;

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.os.RemoteException;
import android.view.View;

public class MainActivity extends Activity {

    private IService  myBinder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    //绑定服务
    public void bindService(View v){
        // 测试一下绑定的服务
        Intent intent = new Intent(this,RemoteService.class);
        bindService(intent, new MyConntion(), BIND_AUTO_CREATE);
    }

    //本地调用服务中的方法
    public void callServiceMethod(View v){
        //调用服务中的业务逻辑方法
        try {
            myBinder.callMethod();
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }


    /**
     * 实现服务的连接
     * @author Administrator
     *
     */
    private class MyConntion implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName arg0, IBinder arg1) {
            myBinder =  (IService) arg1;
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {

        }

    }
}

接下来开始在创建一个项目
这里写图片描述

这里需要把上面远程服务所在的项目的IService的扩展名改为aidl

package com.example.aidl.invoke;

/**
 * 供外面调用的接口
 * @author Administrator
 *
 */
 interface IService {

    /**
     * 供外面操作调用的方法
     */
    void callMethod();

}

把这个扩展名为aidl的文件复制到NativeAPP中,注意连同包名一起复制,这里有个小问题,就是在清单文件中需要价格action:

<service android:name="com.example.aidl.RemoteService">
            <intent-filter >
                <action android:name="com.example.aidl.fly"/>
            </intent-filter>
        </service>

再说明一点,扩展名改为aidl的时候,会在gen文件下面生成一个文件:

/*
 * This file is auto-generated.  DO NOT MODIFY.
 * Original file: D:\\android_EclipseDemo\\RemoteService\\src\\com\\example\\aidl\\invoke\\IService.aidl
 */
package com.example.aidl.invoke;
/**
 * 供外面调用的接口
 * @author Administrator
 *
 */
public interface IService extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements com.example.aidl.invoke.IService
{
private static final java.lang.String DESCRIPTOR = "com.example.aidl.invoke.IService";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
 * Cast an IBinder object into an com.example.aidl.invoke.IService interface,
 * generating a proxy if needed.
 */
public static com.example.aidl.invoke.IService asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof com.example.aidl.invoke.IService))) {
return ((com.example.aidl.invoke.IService)iin);
}
return new com.example.aidl.invoke.IService.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_callMethod:
{
data.enforceInterface(DESCRIPTOR);
this.callMethod();
reply.writeNoException();
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.example.aidl.invoke.IService
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
/**
     * 供外面操作调用的方法
     */
@Override public void callMethod() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_callMethod, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
}
static final int TRANSACTION_callMethod = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
}
/**
     * 供外面操作调用的方法
     */
public void callMethod() throws android.os.RemoteException;
}

重点看这里:

public static abstract class Stub extends android.os.Binder implements com.example.aidl.invoke.IService
{

也就是在代码中不需要去实现IService这个接口,直接继承Stub这个类就好了,

在NativeAPP项目中调用远程服务的方法:

package com.example.nativeapp;

import com.example.aidl.invoke.IService;
import com.example.aidl.invoke.IService.Stub;
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.os.RemoteException;
import android.view.View;

public class MainActivity extends Activity {

    private IService asInterface;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    public void bindService(View v){
        // 隐士意图启动服务
        Intent intent = new Intent();
        intent.setAction("com.example.aidl.fly");
        bindService(intent, new MyConntion(), BIND_AUTO_CREATE);
    }

    //远程服务调用的方法
    public void callServiceMethod(View v){
        try {
            asInterface.callMethod();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }

    /**
     * 服务连接
     * @author Administrator
     *
     */
    private class MyConntion implements ServiceConnection{

        @Override
        public void onServiceConnected(ComponentName arg0, IBinder arg1) {
            asInterface = Stub.asInterface(arg1);
        }

        @Override
        public void onServiceDisconnected(ComponentName arg0) {

        }

    }
}

这样就基本实现了aidl跨进程通信。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值