我是靠谱客的博主 甜美路人,最近开发中收集的这篇文章主要介绍Android中的Binder和AIDL,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

1.Binder
        1.1简介
                Binder是一种进程间通信的机。

                Binder就是Android中的血管,在Android中我们使用Activity,Service等组件都需要                  和AMS (system_server)进行通信,这种跨进程的通信都是通过Binder完成。

                Activity,Service等组件和AMS不是同一个进程,其实也是多进程通信。

        1.2性能
                Binder 相对于传统的 Socket 方式,更加高效。
                Binder数据拷贝只需要一次,而管道、消息队列、 Socket 都需要 2 次,共享内存                  方式一次内存拷贝都不需要,但实现方式又比较复杂。
        1.3安全
                传统的进程通信方式对于通信双方的身份并没有做出严格的验证,比如 Socket 通                  信的 IP 地址是客户端手动填入,很容易进行伪造。
                Binder 机制从协议本身就支持对通信双方做身份校检,从而大大提升了安全性。

2.AIDL
        2.1简介
                AIDL ( Android 接口定义语言),可以使用它定义客户端与服务端进程间通信(                 IPC )的编程接口。在 Android系统中,每个进程都运行在一块独立的内存中,                      在 其中完成自己的各项活动,与其他进程都分 隔开来。可是有时候我们又有应用                  间进行互动的需求,比较传递数据或者任务委托等,AIDL 就是为了满足这种需求                  而诞生的。通过AIDL ,可以在一个进程中获取另一个进程的数据和调用其暴露出                  来的方法,从而满足进程间通信的需求。
                AIDL 是用于定义服务端和客户端通信接口的一种描述语言,可以拿来生产 IPC 代                  码,从某种意义上说
               AIDL 其实就是一个模板,因为在使用过程中,实际起作用的并不是 AIDL 文件,                   而是据此生产的一个Interface的实例代码, AIDL 其实是为了避免我们重复写代码                 而出现的一个模板。

2.2 创建.aildl 文件

系统会自动生产文件夹和aidl文件

2.3 具体的业务对象实现基于 .aidl 文件生成的接口

然后build一下 

2.4 向客户端公开接口

创建一个service公开接口

package com.hp.server;

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

public class PayService extends Service {
    public PayService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
        return new IPayImpl();
    }
    public class IPayImpl extends IPayAidlInterface.Stub{
        private String account;
        private int money;
        @Override
        public void setAccount(String account) throws RemoteException {
            this.account=account;
        }

        @Override
        public void steMoney(int money) throws RemoteException {
            //打开Activity
            Intent intent=new Intent();
            intent.setClass(PayService.this,MainActivity.class);
            //新的 task中打开
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra("money",money);
            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 {

        }
    }
}

2.5 客户端远程调用

创建另一个项目进行测试,首先创建aidl文件夹

在项目所在系统根路径位置中将服务端的aidl文件夹下的.aidl文件连包一起复制粘贴在客户端的main文件夹所在位置的文件夹下。

 然后服务端再build一下,此时就可以具体调用了,具体实现参考如下:

package com.hp.server;

import androidx.appcompat.app.AppCompatActivity;

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.RemoteException;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.hp.client.R;


public class MainActivity extends AppCompatActivity {
    private Button btn_start,btn_stop,btn_call;
    private  IPayAidlInterface iPayAidlInterface;

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

        btn_start=findViewById(R.id.btn_start);
        btn_stop=findViewById(R.id.btn_stop);
        btn_call=findViewById(R.id.btn_call);

        btn_start.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.i("跟Server进行通信","绑定服务");
                Intent intent=new Intent();
                intent.setComponent(new ComponentName("com.hp.server","com.hp.server.PayService"));
                bindService(intent,conn,BIND_AUTO_CREATE);
            }
        });
        btn_stop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                unbindService(conn);
            }
        });
        btn_call.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    iPayAidlInterface.setAccount("x12369");
                    iPayAidlInterface.steMoney(100);
                    String info = iPayAidlInterface.getInfo();
                    Log.i("跟Server进行通信",info);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
    }
    private ServiceConnection conn=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder service) {
            iPayAidlInterface=IPayAidlInterface.Stub.asInterface(service);
            Log.i("跟Server进行通信",iPayAidlInterface+"");
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };
}

:google增加了软件包可见性的限制,targetSdk 版本为30的时候,在Android11 的机型上,AIDL完全不可用,服务也连接不上,但是在低版本的手机上,或者targetSdk 29时候可以用。

在客户端清单文件中加上如下代码即可:

<queries>
    <package android:name="com.wpw.server" />
</queries>

总结:

  1. AIDL是什么?

    Android 通信接口定义语言

  2. AIDL用在哪?

    进程间通信

    1. 如果现在想要进行进程间通信,应该如何操作?

    2. 服务端应该做什么?

      1.  定义.aidl文件,定义具体业务的抽象方法
      2.  将项目rebuild,系统会自动生成和.aidl文件同名的java文件
      3.  创建新的类,让类继承 接口.Stub
      4.  向客户端公开接口,依托于服务
    3. 客户端做什么?

      1.  将服务器的.aidl连包一起放入客户端,将项目rebuild
      ​
      2.  在Activity中绑定服务
      ​
      1.  在绑定服务的过程中,发现无法对服务器公开的接口进行连接(API 30)

      在AndroidManifest.xml 添加

       ```
       <querys>
          <package android:name="com.hopu.server" />
       </querys>
       ```
      1. 绑定服务后,跟服务器开始进行对话

最后

以上就是甜美路人为你收集整理的Android中的Binder和AIDL的全部内容,希望文章能够帮你解决Android中的Binder和AIDL所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部