Android:AIDL

目录

AIDL是什么?

使用流程

AIDL的使用(同一个app中activity与service的通信)

两个APP进行AIDL通信


AIDL是什么?

        AIDL(Android接口定义语言),可以使用它定义客户端与服务端进程间通信(IPC)的编程接口。在Android系统中,每个进程都运行在一个独立的内存中,在其中完成自己的各项活动,与其他进程都分隔开来。可是有时候我们又有应用间进行通信的需求,比较传递数据或任务委托等,AIDL就是为了满足这种需求而诞生的。通过AIDL可以在一个进程中获取另一个进程的数据和其暴漏出来的方法,从而满足进程间通信的需求。

AIDL 是用于定义服务端和客户端通信接口的一种描述语言,可以拿来生产 IPC 代码,从某种意义上说 AIDL其实就是一个模板,因为在使用过程中,实际起作用的并不是 AIDL 文件,而是据此生产的一个 Interface的实例代码, AIDL 其实是为了避免我们重复写代码而出现的一个模板。
注意:只有需要在不同应用的客户端通过IPC方式访问服务,并且希望在服务中进行多线程处理时,您才有必要使用AIDL。如果您无需跨不同应用执行并发IPC,则通过实现Binder来创建接口,或者,您如果想执行IPC,但不需要处理多线程,请使用Messenger来实现接口。无论如何,在使用AIDL前请您务必理解解绑业务

使用流程

  1. 在.aidl文件中定义AIDL接口,并将其添加到应用工程的src目录下,创建完成之后rebuild
  2. 在Android SDK 工具会自动生成基于该.aidl文件的IBinder接口,具体的业务对象实现这个接口。这个具体的业务对象也是IBinder对象,但绑定服务的时候会根据实际情况返回具体的通信对象(本地还是代理)
  3. 将客户端绑定到该服务上,之后就可以调用IBinder中的方法来进行进程间通信(IPC)

AIDL的使用(同一个app中activity与service的通信)

  1. 现在工程的src目录下创建.aidl文件
  2. 打开生成的aidl文件,在其中添加具体的业务方法如:
    // ILoginAidlInterface.aidl
    package com.shy.myserverwork;
    
    // Declare any non-default types here with import statements
    
    interface ILoginAidlInterface {
         //自己添加的业务
         void setAccount(String account);
         void setPwd(String pwd);
         boolean getInfo();
    
        //自动生成的
        /**
         * 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);
    }

    然后rebuild,Android SDK工具会在相应的目录生成对应的.aidl文件同名的 .java接口文件

  3. 这个业务需要一个具体的实现类来完成,创建一个类并继承接口下的stud抽象类

    package com.shy.payserver;
    
    import android.content.Intent;
    import android.os.IBinder;
    import android.os.RemoteException;
    
    
    public class PayImpl extends IPayAidlInterface.Stub{
            String account;
            double money;
    
            @Override
            public void setAccount(String account) throws RemoteException {
                this.account=account;
            }
    
            @Override
            public void setMoney(double money) throws RemoteException {
    
                this.money = money;
            }
    
            @Override
            public String getInfo() throws RemoteException {
                return "账号:"+account+"金额:"+money;
            }
    
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
    
            }
        }
    
    }

    创建一个服务Service以便于对外提供具体的业务

    public class PayService extends Service {
        public PayService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return new PayImpl();
        }
  4. 客户端远程调用

    //建立连接 
    Intent intent=new Intent();
            intent.setComponent(new 
            bindService(intent,conn,BIND_AUTO_CREATE); 
        //进行通信
      iLoginAidlInterface.setAccount(pwd);
                        iLoginAidlInterface.setPwd(account);
                        flag=iLoginAidlInterface.getInfo();
    
    
    public ServiceConnection conn=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                iLoginAidlInterface=ILoginAidlInterface.Stub.asInterface(service);
                Log.i("TAG", "onServiceConnected: "+iLoginAidlInterface);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };

两个APP进行AIDL通信

  1. 创建服务端APP
  2. 创建一个aidl文件只做业务逻辑接口并且rebuild
    interface IPayAidlInterface {
        void setAccount(String account);
        void setMoney(double money);
        String getInfo();
        /**
         * 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);
    }
  3. 创建一个类实现stub,并完成业务逻辑(我把它作为了service的内部类)

  4. 将接口暴露出去,使用service

    public class PayService extends Service {
        public PayService() {
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            return new PayImpl();
        }
    
    
        public class PayImpl extends IPayAidlInterface.Stub{
            String account;
            double money;
    
            @Override
            public void setAccount(String account) throws RemoteException {
                this.account=account;
            }
    
            @Override
            public void setMoney(double money) throws RemoteException {
                Intent intent=new Intent(PayService.this,MainActivity.class);
    //            startActivity(intent);
                intent.putExtra("name",account);
                intent.putExtra("money",money);
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                this.money = money;
            }
    
            @Override
            public String getInfo() throws RemoteException {
                return "账号:"+account+"金额:"+money;
            }
    
            @Override
            public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
    
            }
        }
    
    }

  5. 创建客户端APP

  6. 将服务器中的.aidl文件复制到客户端中

  7. 在Activity中绑定,使用接收到的IBinder进行通信

    public class MainActivity extends AppCompatActivity {
        private ILoginAidlInterface iLoginAidlInterface;
        public Button btn_login;
        private TextInputEditText et_account,et_pwd;
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            btn_login=findViewById(R.id.btn_login);
            et_account=findViewById(R.id.et_account);
            et_pwd=findViewById(R.id.et_pwd);
    
    
            Intent intent=new Intent();
            intent.setComponent(new ComponentName("com.shy.myserverwork","com.shy.myserverwork.MyBindService"));
            bindService(intent,conn,BIND_AUTO_CREATE);
    
    
            btn_login.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    String pwd= et_pwd.getText().toString();
                    String account= et_account.getText().toString();
                    boolean flag;
                    try {
                        iLoginAidlInterface.setAccount(pwd);
                        iLoginAidlInterface.setPwd(account);
                        flag=iLoginAidlInterface.getInfo();
                        if (flag){
    
                        }else {
                            Toast.makeText(MainActivity.this, "登陆失败", Toast.LENGTH_SHORT).show();
                        }
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
    
        }
        public ServiceConnection conn=new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                iLoginAidlInterface=ILoginAidlInterface.Stub.asInterface(service);
                Log.i("TAG", "onServiceConnected: "+iLoginAidlInterface);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    }

    注意:如果您的应用以 Android 10(API 级别 29)或更低版本为目标平台,那么全部应用均会自动对您的应用可见。
    如果您的应用以 Android 11(API 级别 30)或更高版本为目标平台,并且需要与应用(自动可见的应用除外)交互,请在您应用的清单文件中添加 <queries> 元素。在 <queries> 元素中,按软件包名称、按 intent 签名或按提供程序授权指定其他应用,如以下部分所述。查询特定软件包及与之交互

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        package="com.shy.client">
        <queries>
            <package android:name="com.shy.myserverwork"/>
        </queries>
        ...
    </manifest>

猜你喜欢

转载自blog.csdn.net/m0_60623666/article/details/126088824