android AIDL 语言用法

跨进程通信可以用AIDL语言

这里讲述下如何使用AIDL语言进行跨进程通信

文章参考 《设计模式》一书

demo结构参考

主要的文件类有:IBankAidl.aidl

java文件:AidlBankBinder,BackActivity(应该是BankActivity写错了),BankService(继承自Service,服务类)

IBankAidl.aidl文件 这里AIdl的使用对包位置有要求,所以我就把包名放出来了

package finishdemo.arcturis.binderandserviceandaidl.binder;

// Declare any non-default types here with import statements

interface IBankAidl {
    /**
     * 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);
   /**
     * 开户
     * @param name 户主名
     * @param password 密码
     * @return 开户信息
     */
    String openAccount(String name,String password);

    /**
     * 存钱
     * @param money
     * @param account
     * @return
     */
    String saveMoney(int money,String account);

    /**
     * 取钱
     * @param money
     * @param account
     * @param password
     * @return
     */
    String takeMoney(int money,String account,String password);

    /**
     * 销户
     * @param account
     * @param password
     * @return
     */
    String closeAccount(String account,String password);

}

AidlBankBinder文件 继承自IBankAidl的Stub类,然后重写并实现Aidl内的方法,这里是模拟一个银行的操作

public class AidlBankBinder extends IBankAidl.Stub {

    @Override
    public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
    }

    @Override
    public String openAccount(String name, String password) {
        return name+"开户成功!账号为:"+ UUID.randomUUID().toString();
    }

    @Override
    public String saveMoney(int money, String account) {
        return "账户:"+account + "存入"+ money + "单位:人民币";
    }

    @Override
    public String takeMoney(int money, String account, String password) {
        return "账户:"+account + "支取"+ money + "单位:人民币";
    }

    @Override
    public String closeAccount(String account, String password) {
        return account + "销户成功";
    }
}

BankService文件 返回一个AidlBankBinder

public class BankService extends Service {

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        //单进程写法
//        return new BankBinder();
        //不同进程AIDL 通信写法
        return new AidlBankBinder();
    }
}

接下来在Activity中使用 BackActivity方法

public class BackActivity extends AppCompatActivity implements View.OnClickListener {

//    private BankBinder mBankBinder;
    private IBankAidl mBankBinder;

    private TextView tvMsg;

    private Context context;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //同一进程写法
//            mBankBinder = (BankBinder) service;
            //不同进程写法
            mBankBinder = IBankAidl.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {

        }
    };

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        context = this;
        tvMsg = (TextView) findViewById(R.id.tv_msg);

        Intent intent = new Intent();
        intent.setAction("actionname.aidl.bank.BankService");

        //这里遇到一个问题,如果你直接使用intent 这个意图去开启服务的话就会报
        //Android Service Intent must be explicit 意思是服务必须要显示的调用,这个是5.0之后新的规定
        //这个 createExplicitFromImplicitIntent 可以将隐性调用变成显性调用
        Intent intent1  = new Intent(createExplicitFromImplicitIntent(context,intent));

        bindService(intent1,conn,BIND_AUTO_CREATE);

        initBtn(R.id.btn_aidl_bank_close);
        initBtn(R.id.btn_aidl_bank_open);
        initBtn(R.id.btn_aidl_bank_save);
        initBtn(R.id.btn_aidl_bank_take);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }

    private void initBtn(int resID){
        Button b = (Button) findViewById(resID);
        b.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_aidl_bank_open:
                //这个RemoteException 是 AIDL跨进程通信的用法必须加上的异常捕获
                try {
                    tvMsg.setText(mBankBinder.openAccount("BigAss","123456"));
                }catch (RemoteException e){
                    e.printStackTrace();
                }
                break;

            case R.id.btn_aidl_bank_save:
                try {
                    tvMsg.setText(mBankBinder.saveMoney(8888888,"bigAss123"));
                }catch (RemoteException e){
                    e.printStackTrace();
                }
                break;

            case R.id.btn_aidl_bank_take:
                try {
                    tvMsg.setText(mBankBinder.takeMoney(520,"bigAss123","123456"));
                }catch (RemoteException e){
                    e.printStackTrace();
                }
                break;

            case R.id.btn_aidl_bank_close:
                try {
                    tvMsg.setText(mBankBinder.closeAccount("bigAss123","123456"));
                }catch (RemoteException e){
                    e.printStackTrace();
                }
                break;

        }
    }

    /***
     * Android L (lollipop, API 21) introduced a new problem when trying to invoke implicit intent,
     * "java.lang.IllegalArgumentException: Service Intent must be explicit"
     *
     * If you are using an implicit intent, and know only 1 target would answer this intent,
     * This method will help you turn the implicit intent into the explicit form.
     *
     * Inspired from SO answer: http://stackoverflow.com/a/26318757/1446466
     * @param context
     * @param implicitIntent - The original implicit intent
     * @return Explicit Intent created from the implicit original intent
     */
    public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List<ResolveInfo> resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        // Make sure only one match was found
        if (resolveInfo == null || resolveInfo.size() != 1) {
            return null;
        }

        // Get component info and create ComponentName
        ResolveInfo serviceInfo = resolveInfo.get(0);
        String packageName = serviceInfo.serviceInfo.packageName;
        String className = serviceInfo.serviceInfo.name;
        ComponentName component = new ComponentName(packageName, className);

        // Create a new intent. Use the old one for extras and such reuse
        Intent explicitIntent = new Intent(implicitIntent);

        // Set the component to be explicit
        explicitIntent.setComponent(component);

        return explicitIntent;
    }
}

主要思路是用隐式的方法启动一个服务,然后调用Aidl实例类的方法即可,具体的Aidl语言在BuildApp之后在

这里即可查看 内部是他实现进程间数据传输所做的转化代码,有兴趣可以看下

原文地址:https://www.cnblogs.com/fengfenghuifei/p/8418965.html

时间: 2024-11-14 00:47:50

android AIDL 语言用法的相关文章

Android AIDL的用法

一.什么是AIDL服务 一般创建的服务并不能被其他的应用程序访问.为了使其他的应用程序也可以访问本应用程序提供的服务,Android系统采用了远程过程调用(Remote Procedure Call,RPC)方式来实现.与很多其他的基于RPC的解决方案一样,Android使用一种接口定义语言(Interface Definition Language,IDL)来公开服务的接口.因此,可以将这种可以跨进程访问的服务称为AIDL(Android Interface Definition Langua

Android AIDL使用详解

1.什么是aidl:aidl是 Android Interface definition language的缩写,一看就明白,它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口 icp:interprocess communication :内部进程通信 2.既然aidl可以定义并实现进程通信,那么我们怎么使用它呢?文档/android-sdk/docs/guide/developing/tools/aidl.html中对步骤作了详细描述: --1.Create

android aidl摘要

/*在Android中, 每个应用程序都有自己的进程,当需要在不同的进程之间传递对象时,该如何实现呢? 显然, Java中是不支持跨进程内存共享的.因此要传递对象, 需要把对象解析成操作系统能够理解的数据格式, 以达到跨界对象访问的目的.在JavaEE中,采用RMI通过序列化传递对象.在Android中, 则采用AIDL(Android Interface Definition Language:接口描述语言)方式实现. AIDL是一种接口定义语言,用于约束两个进程间的通讯规则,供编译器生成代码

Android AIDL 小结

1.AIDL (Android Interface Definition Language ) 2.AIDL 适用于 进程间通信,并且与Service端多个线程并发的情况,如果只是单个线程 可以使用 Messenger ,如果不需要IPC 可以使用Binder 3.AIDL语法:基础数据类型都可以适用,List Map等有限适用.static field 不适用. 4.AIDL基本用法 第一步:实现.aidl文件 接口描述文件 1.导入的包名 2.如果有使用Object对象,需要该对象 impl

(转载)你真的理解Android AIDL中的in,out,inout么?

前言 这其实是一个很小的知识点,大部分人在使用AIDL的过程中也基本没有因为这个出现过错误,正因为它小,所以在大部分的网上关于AIDL的文章中,它都被忽视了--或者并没有,但所占篇幅甚小,且基本上都是官方文档的译文,译者读者其实都不知其然.这几天在研究AIDL,偏偏我又是个执拗的性子,遇着不清不楚的东西就是想把它捋清楚,就下了些功夫研究了下AIDL中的定向tag,研究了下它的 in , out , inout . 整理而成此博文. 1.概述 首先要说的是定向tag是AIDL语法的一部分,而 in

Android初始化语言

init.rc 文件并不是普通的配置文件,而是由一种被称为"Android初始化语言"(Android Init Language,这里简称为AIL)的脚本写成的文件. AIL由如下4部分组成: 1.  动作(Actions) 2.  命令(Commands) 3.服务(Services) 4.  选项(Options) 这4部分都是面向行的代码,也就是说用回车换行符作为每一条语句的分隔符.而每一行的代码由多个符号(Tokens)表示.可以使用反斜杠转义符在 Token中插入空格.双引

Android aidl Binder框架浅析

转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38461079 ,本文出自[张鸿洋的博客] 1.概述 Binder能干什么?Binder可以提供系统中任何程序都可以访问的全局服务.这个功能当然是任何系统都应该提供的,下面我们简单看一下Android的Binder的框架 Android Binder框架分为服务器接口.Binder驱动.以及客户端接口:简单想一下,需要提供一个全局服务,那么全局服务那端即是服务器接口,任何程序即客

Android aidl通信详解

前段时间研究了不少android二次开发,其中有一种方法就是通过aidl通信,留接口提供给外面二次开发.从这里也可以看出:aidl通信是两个应用程序之间的进程通信了.在这篇博客中,主要写了两个应用程序,一个是serverdemo,可以称为服务端,也是提供接口的应用程序,在这里面我写了一个加法计算.二是客户端:clientdemo,在这个程序中调用了加法计算接口,把值传到serverdemo进行加法计算,返回结果,进行显示. 1.aidl的定义 aidl是 Android Interface de

Android 初始化语言 --init.rc

p.p1 { margin: 0.0px 0.0px 12.9px 0.0px; line-height: 24.0px; font: 21.0px Helvetica; color: #000000; background-color: #ffffff } p.p2 { margin: 0.0px 0.0px 10.0px 0.0px; line-height: 16.0px; font: 14.0px "PingFang SC"; color: #000000; backgroun