Android进程间的通信之AIDL

Android服务被设计用来执行很多操作,比如说,可以执行运行时间长的耗时操作,比较耗时的网络操作,甚至是在一个单独进程中的永不会结束的操作。实现这些操作之一是通过Android接口定义语言(AIDL)来完成的。AIDL被设计用来执行进程间通信,另一种实现方式见博文Android进程间的通信之Messenger。本文我们将学习如何创建AIDL文件实现Android进程间通信。在正式学习之前,我们先澄清一些“事实”。

关于Android Service

1、Android服务不是后台任务,它们默认只运行在你的app的主线程中
2、Android服务可以通过设置来运行在不同进程中
3、如果Android服务在不同进程中启动,你将不能使用通常的IBinder接口与其通信

AIDL:Android Interface Definition Language

为了在Android应用中实现进程间通信,我们需要在远端进程中定义一系列可被当前进程访问的方法。通过AIDL我们可以定义这样的一系列方法。AIDL就好像Java中的其它接口一样可以在其中定义一些抽象方法。我们首先需要创建一个以.aidl为后缀的文件并在里面定义所需的抽象方法。

AIDL的一个主要特征是,通过使用AIDL,我们可以在两个不同的应用中进行通信(其实Messenger也可以实现同样的操作,两者区别请见博文Android进程间的通信之Messenger);当然,如果你的应用不需要跟另外一个应用进行通信,那就尽量避免使用AIDL机制吧。aidl文件中定义的抽象方法中,只有一些原始数据类型以及一些基本数据类型如String,lists,maps等可以作为这些方法的参数,如果你想使用一个自定义类作为参数,那么你的自定义类必须实现Parcelable接口,并且该类要被导入AIDL文件中,这一点应该在单独的课程中进行讲解。本文只学习简单的AIDL用法。

AIDL实现思路

AIDL通过定义服务端暴露的接口,以提供给客户端来调用,AIDL使服务端可以并行处理(因此你可能需要考虑多线程并发访问的线程安全性问题)。通过编写aidl文件来设计想要暴露的接口,编译后会自动生成相应的Java文件,服务端将接口的具体实现写入Stub中,通过IBinder对象传递给客户端,客户端bindService时,通过asInterface方法将IBinder还原成接口,供客户端调用其中的方法。

简单示例

AndroidManifest.xml

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <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=".BoundService" android:process=":custom_process"/>
</application>

IBoundService.aidl

package yf.exam.service.aidl;
interface IBoundService{
    int getResult(int a, int b);
}

BoundService.java

public class BoundService extends Service {
    private IBoundService.Stub mBinder = new IBoundService.Stub() {
        @Override
        public int getResult(int a, int b) throws RemoteException {
            return a+b;
        }
    };
    @Override
    public IBinder onBind(Intent intent) {
        return mBinder;
    }
}

MainActivity.java

public class MainActivity extends Activity {
    private Button btn = null;
    private IBoundService mIBoundService;
    private boolean mServiceConnected = false;
    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            mServiceConnected = false;
        }
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mIBoundService = IBoundService.Stub.asInterface(service);
            mServiceConnected = true;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        btn = (Button) findViewById(R.id.button1);
        Intent intent = new Intent(this, BoundService.class);
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (mServiceConnected) {
                    try {
                        int result = mIBoundService.getResult(2, 4);
                        Toast.makeText(MainActivity.this, "result=" + result,
                                Toast.LENGTH_SHORT).show();
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mServiceConnected) {
            unbindService(conn);
            mServiceConnected = false;
        }
    }
}
时间: 2024-08-02 06:59:18

Android进程间的通信之AIDL的相关文章

从AIDL开始谈Android进程间Binder通信机制

本文首先概述了Android的进程间通信的Binder机制,然后结合一个AIDL的例子,对Binder机制进行了解析. 概述 我们知道,在Android app中的众多activity,service等组件可以运行在同一进程中,也可以运行在不同进程中.当组件运行在同一进程中进行通信就显得比较简单,在之前的Android线程间通信机制中已经讲过了:而当它们运行在不同的进程中时,就需要使用我们本文中所要介绍的Binder机制了. Binder作为一种进程间通信机制,负责提供远程调用的功能(RPC),

Android进程间的通信

1.概述:由于android系统中应用程序之间不能共享内存.因此,在不同应用程序之间交互数据(跨进程通讯)就稍微麻烦一些.在android SDK中提供了4种用于跨进程通讯的方式.这4种方式正好对应于android系统中4种应用程序组件:Activity.Content Provider.Broadcast和Service.其中Activity可以跨进程调用其他应用程序的Activity:Content Provider可以跨进程访问其他应用程序中的数据(以Cursor对象形式返回),当然,也可

Android进程间的通信之Messenger

Android进程间的通信方式可以通过以下两种方式完成: 1 Android接口定义语言(AIDL) 2 使用Messenger绑定服务 本文我们将学习使用Messenger绑定服务的方式进行进程间的通信. Android AIDL和Messenger区别 使用Messenger是执行进程间通信最简单的方法,因为Messenger会在单一线程中创建包含所有请求的队列,这样您就不必对服务进行线程安全设计.而纯粹的AIDL接口会同时向服务发送多个请求,服务随后必须应对多线程处理.AIDL通常应用在服

Android 使用AIDL实现进程间的通信

在Android中,如果我们需要在不同进程间实现通信,就需要用到AIDL技术去完成. AIDL(android Interface Definition Language)是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作.关于AIDL的编写规则我在这里就不多介绍了,读者可以到网上查找一下相关资料. 接下来,我就演示一个操作AIDL的最基本的流程. 首先,我

Android进阶笔记04:Android进程间通讯之Messenger ( 区别于AIDL)

一. Android进程间通讯之Messenger 的引入 (1)引言:      平时一说进程间通讯,大家都会想到AIDL,其实messenger和AIDL作用一样,都可以进行进程间通讯.它是基于消息的进程间通信,就像子线程和UI线程发送消息那样,是不是很简单,还不用去写AIDL文件,是不是有点小爽.哈哈.此外,还支持记录客户端对象的Messenger,然后可以实现一对多的通信:甚至作为一个转接处,任意两个进程都能通过服务端进行通信. (2) Messenger 与 AIDL 比较:    

【转】使用AIDL实现进程间的通信之复杂类型传递

使用AIDL实现进程间的通信之复杂类型传递 首先要了解一下AIDL对Java类型的支持. 1.AIDL支持Java原始数据类型. 2.AIDL支持String和CharSequence. 3.AIDL支持传递其他AIDL接口,但你引用的每个AIDL接口都需要一个import语句,即使位于同一个包中. 4.AIDL支持传递实现了android.os.Parcelable接口的复杂类型,同样在引用这些类型时也需要import语句.(Parcelable接口告诉Android运行时在封送(marsha

使用AIDL实现进程间的通信

在Android中,如果我们需要在不同进程间实现通信,就需要用到AIDL技术去完成. AIDL(Android Interface Definition Language)是一种接口定义语言,编译器通过*.aidl文件的描述信息生成符合通信协议的Java代码,我们无需自己去写这段繁杂的代码,只需要在需要的时候调用即可,通过这种方式我们就可以完成进程间的通信工作.关于AIDL的编写规则我在这里就不多介绍了,读者可以到网上查找一下相关资料. 接下来,我就演示一个操作AIDL的最基本的流程. 首先,我

进程间的通信如何实现

进程间的通信如何实现 版权声明:本文为博主原创文章,未经博主允许不得转载.

linux 进程间的通信

现在linux使用的进程间通信方式:(1)管道(pipe)和有名管道(FIFO)(2)信号(signal)(3)消息队列(4)共享内存(5)信号量(6)套接字(socket) 为何进行进程间的通信:A.数据传输:一个进程需要将它的数据发送给另一个进程,发送的数据量在一个字节到几M字节之间B.共享数据:多个进程想要操作共享数据,一个进程对共享数据的修改,别的进程应该立刻看到.C.通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程).D.资源共享