(转自)可以参见:http://www.2cto.com/kf/201406/312244.html

1、为什么要有AIDL?

  无论学什么东西,最先得弄明白为什么要有这个东西,不要说存在即是合理,存在肯定合理,但是你还是没有明白。对于AIDL有一些人的浅显概念就是,AIDL可以跨进程访问其他应用程序,和其他应用程序通讯,那我告诉你,很多技术都可以访问,如广播(应用A在AndroidManifest.xml中注册指定Action的广播)应用B发送指定Action的广播,A就能收到信息,这样也能看成不同应用之间完成了通讯(但是这种通讯是单向的);还如ContentProvider,通过URI接口暴露数据给其他应用访问;但是这种都算不上是应用之间的通讯。可能最让人迷惑的是Android推出来了Messager,它就是完成应用之间的通讯的。那么为什么还要有AIDL呢,官方文档介绍AIDL中有这么一句话:

  Note: Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service. If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.

  第一句最重要,“只有当你允许来自不同的客户端访问你的服务并且需要处理多线程问题时你才必须使用AIDL”,其他情况下你都可以选择其他方法,如使用Messager,也能跨进程通讯。可见AIDL是处理多线程、多客户端并发访问的。而Messager是单线程处理。还是官方文档说的明白,一句话就可以理解为什么要有AIDL。那么是不是这样的写个AIDL试试。

2、AIDL使用

  1. 定义AIDL文件

     // IRemoteService.aidl
    package com.example.android; // Declare any non-default types here with import statements /** Example service interface */
    interface IRemoteService {
    /** Request the process ID of this service, to do evil things with it. */
    int getPid(); /** Demonstrates some basic types that you can use as parameters
    * and return values in AIDL.
    */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
    double aDouble, String aString);
    }

    这段代码也是官方文档的。命名为IRemoteService.aidl,放在com.example.android包下(这个可以随意),保存后Android编译器会在gen目录下自动生成IRemoteService.java文件

  2. 定义我们的服务,DDService.java,并且需要在AndroidManifest.xml中注册,并添加“duanqing.test.aidl” 的ACTION。这样我们的服务端就完成了,把服务端运行到模拟器(或者手机上),等一会可以看一下打印信息,重点看“线程名”

     package com.example.service;
    
     import com.example.android.IRemoteService;
    
     import android.app.Service;
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.Process; public class DDService extends Service {
    @Override
    public void onCreate() {
    super.onCreate();
    System.out.println("DDService onCreate........" + "Thread: " + Thread.currentThread().getName());
    }
    @Override
    public IBinder onBind(Intent arg0) {
    System.out.println("DDService onBind");
    return mBinder;
    } private final IRemoteService.Stub mBinder = new IRemoteService.Stub() {
    public int getPid(){
    System.out.println("Thread: " + Thread.currentThread().getName());
    System.out.println("DDService getPid ");
    return Process.myPid();
    }
    public void basicTypes(int anInt, long aLong, boolean aBoolean,
    float aFloat, double aDouble, String aString) {
    System.out.println("Thread: " + Thread.currentThread().getName());
    System.out.println("basicTypes aDouble: " + aDouble +" anInt: " + anInt+" aBoolean " + aBoolean+" aString " + aString);
    }
    }; }
  3. 实现客户端测试代码 新建另一个工程,同样需要添加AIDL协议文件(这是一个标准的协议文件,定义对外服务),这里我列出来我的测试代码
     package com.example.aidlclient;
    
     import android.app.Activity;
    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.os.Process;
    import android.os.RemoteException;
    import android.view.View; import com.example.android.IRemoteService; public class MainActivity extends Activity {
    private IRemoteService remoteService;
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    } ServiceConnection conn = new ServiceConnection() { @Override
    public void onServiceDisconnected(ComponentName name) {
    } @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
    remoteService = IRemoteService.Stub.asInterface(service);
    try {
    int pid = remoteService.getPid();
    int currentPid = Process.myPid();
    System.out.println("currentPID: " + currentPid +" remotePID: " + pid);
    remoteService.basicTypes(12, 1223, true, 12.2f, 12.3, "我们的爱,我明白");
    } catch (RemoteException e) {
    e.printStackTrace();
    }
    System.out.println("bind success! " + remoteService.toString());
    }
    }; /**
    * 监听按钮点击
    * @param view
    */
    public void buttonClick(View view) {
    System.out.println("begin bindService");
    Intent intent = new Intent("duanqing.test.aidl");
    bindService(intent, conn, Context.BIND_AUTO_CREATE);
    } @Override
    protected void onDestroy() {
    super.onDestroy();
    unbindService(conn);
    }
    }
  4. 执行 点击客户端按钮,执行,看打印信息:
    看服务端打印,DDService onCreate..........Thread: main,主线程,当客户端调用服务端getPid方法时,服务端是在Thread: Binder2中执行,当客户端调用服务端basicType方法时,服务端是在Thread:Binder1中执行

 

4、

AIDL学习的更多相关文章

  1. android中的AIDL学习笔记

    一.定义 AIDL是用来解决进程间通信的(一般有四种方式:Activity.Service.ContentProvider.Broadcast Receiver),两个进程间无法直接通信,所以要用AI ...

  2. Android -- Service绑定解绑和aidl

    Service是安卓四大组件之一,先前讲到了Service的生命周期,以及非绑定类型的生命周期的例子,这次来分享一下绑定形式的. 应用组件(客户端)可以调用bindService()绑定到一个serv ...

  3. 如何自学Android--转

    原文地址:http://blog.csdn.net/lavor_zl/article/details/51217319 1. Java知识储备 本知识点不做重点讲解: 对于有基础的同学推荐看<J ...

  4. 如何自学 Android 的?

    http://android.jobbole.com/83380/ 1. Java知识储备 本知识点不做重点讲解:对于有基础的同学推荐看<Java编程思想>,巩固基础,查漏补全,了解并熟悉 ...

  5. 我是怎样自学 Android 的?

    1. Java知识储备 本知识点不做重点解说: 对于有基础的同学推荐看<Java编程思想>,巩固基础,查漏补全,了解并熟悉很多其它细节知识点. 对于没有基础的同学推荐看一本Java基础的书 ...

  6. Android 学习笔记 Service服务与远程通信...(AIDL)

    PS:这一章节看的我有几分迷茫,不是很容易理解...不过还好总算是明白了一大半了...基本的迷惑是解决了... 学习内容: 1.跨应用启动服务... 2.跨应用绑定服务... 3.跨应用实现通信... ...

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

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

  8. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

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

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

随机推荐

  1. HTML5新增video标签及对应属性、API详解

    知识说明: 比不上很牛的前端开发人员,但自始至终明白“万丈高楼平地起”,基础最重要,初学HTML5,稳固基础第一步,把最基本的整理下来,留下自己学习的痕迹.HTML5新增的video标签,将其属性以及 ...

  2. 无线网络的切换bat

    内网外网都是无线,切换起来麻烦,做了两个个bat(注意,切换网络的时候有延时,就点两次). -------------------下面的是切换到内网-------------------------- ...

  3. join()、implode()函数

    join() 函数 join() 函数把数组元素组合为一个字符串. join() 函数是 implode() 函数的别名. 语法 join(separator,array) 参数 描述 separat ...

  4. android 检测网络是否连接,或者GPS是否可用

    很多android程序在打开时,检测网络是否连接,或者GPS是否可用: 1.网络是否连接(包括Wifi和移动网络) // 是否有可用网络 private boolean isNetworkConnec ...

  5. PHP7在linux下的安装步骤

    安装mcrypt: yum install -y php-mcrypt libmcrypt libmcrypt-devel 升级bison: cd /var/soft/ wget http://ftp ...

  6. (实用篇)php数组查找函数in_array()、array_search()、array_key_exists()使用

    php在数组中查找指定值是否存在的方法有很多,记得很久以前我一直都是傻傻的用foreach循环来查找的,下面我主要分享一下用php内置的三个数组函数来查找指定值是否存在于数组中,这三个数组分别是 in ...

  7. Neo4j 两种索引Legacy Index与Schema Index区别

    Legacy Indexes 在Neo4j 2.0版本之前,Legacy index被称作indexes.这个索引是通过外部图存储在外的Lucene实现,允许“节点”和“联系”以key:value键值 ...

  8. IIS 发布网站 ashx无法访问

    IIS6 问题 1.是否安装相应的.net版本 2.查看.net版本是否一致 3.查看web 服务扩展中.net版本是否允许. 4.添加相应的MIME类型文件 在IIS中右键网站→属性→主目录→配置→ ...

  9. web安全之sql注入原理

    sql注入的原理:        将(恶意)的SQL命令注入到后台数据库引擎执行的能力,把信息返回到页面 sql注入产生的原因:      过滤不严谨,导致产生的sql注入. sql注入产生的地方:  ...

  10. 在Windows上,迁移VisualSVN server

    最近在搭建自动化测试框架,顺便了解了一下SVN的搭建.对于一般的使用场景,VisualSVN还是挺方便的,而且上手特别快. 由于是第一个demo,后期要迁移到其他服务器上面,所以就熟悉了一下serve ...