• AIDL介绍以及简单使用


    一. AIDL 介绍.

     AIDL(Android接口描述语言)是一个IDL语言,它可以生成一段代码,可以是一个在Android设备上运行的两个进程使用内部通信进程进行交互。
    

    如果你想在一个进程中(例如在一个Activity中)访问另一个进程中(例如service)某个对象的方法,你就可以使用AIDL来生成这样的代码来伪装传递各种参数。

    稍微了解下几个常见的名词(IPC,匿名共享内存,Binder,Aidl,消息,广播,ContentProvider,Intent):
    IPC是一种概念,即进程间通信;其它几个都是Android里的概念;
    **匿名共享内存(Anonymous Shared Memory):其作用之一即通过Binder进程间通信机制来实现进程间的内存共享。 **
    Binder:Binder是对IPC的具体实行,是IPC的一种具体实现.其本质也是调用系统底层的共享内存实现.
    AIDL:进程间的通信,速度快(系统底层直接是共享内存),性能稳,效率高,一般进程间通信就用它. AIDL是Binder机制向外提供的接口,目的就是为了方便对Binder的使用;
    消息(Messager):Messenger本质也是AIDL,只是进行了封装,开发的时候不用再写.aidl文件,效率应该是和Aidl是一样的,与Aidl的区别在于Messager是线程安全的,而Aidl是非线程安全的,所以Aidl在使用的时候应该注意这个问题;
    广播(BroadcastReceiver):只要注册了广播,都能收到,有点范围广,缺点速度慢必须在一定时间完成处理操作,同其他Android四大组件一样,都不能执行耗时操作;
    ContentProvider:暴露app的数据访问接口,让其他应该访问app数据.同时也能通过ContentProvider来访问第三方的一些app数据(如通讯录,日历等暴露接口的应用);
    Intent:Intent是最高层级的封装,实质是封装了对Binder的使用,当然Intent也常常在同一进程中调用,只是把两种方式封装在一起了.

    二. AIDL简单应用.##

    编写两个app应用程序,一个实现Aidl传递的Server端,一个实现Aidl的Client端:
    aidl的Server端,接收Client端传过来的两个int值,定义一个加法计算的逻辑规则, 并返回 两个int数之和, return num1 + num2;
    aidl的Client端,从界面用户输入两个int数,点击绑定Server端服务,点击计算,调用Server端加法逻辑,将返回结果 输入到用户界面展示,两数之和.
    

    Aidl_Server端###

    // IImoocAIDL.aidl
     package com.example.administrator.aidl_server.service;
    
    // Declare any non-default types here with import statements
    
    interface IImoocAIDL {
         //计算num1 + num2
            int add(int num1,int num2);
    }
    

    编译后会生成

    public interface IImoocAIDL extends android.os.IInterface {
        /**
         * Local-side IPC implementation stub class.
         */
        public static abstract class Stub extends android.os.Binder implements com.example.administrator.aidl_server.service.IImoocAIDL {
    			...
    			private static class Proxy implements com.example.administrator.aidl_server.service.IImoocAIDL {
                private android.os.IBinder mRemote;
    
                Proxy(android.os.IBinder remote) {
                    mRemote = remote;
                }
    
                @Override
                public android.os.IBinder asBinder() {
                    return mRemote;
                }
    
                public java.lang.String getInterfaceDescriptor() {
                    return DESCRIPTOR;
                }
    
                @Override
                public int add(int num1, int num2) throws android.os.RemoteException {
    				...
    			}
    			
    			...
    		}
    			...
    	}
    }
    

    //om.example.administrator.aidl_server.IRemoteService

    public class IRemoteService extends Service {
        public static final String TAG = "IRemoteService";
        //客户端绑定service时会执行
        @Override
        public IBinder onBind(Intent intent) {
            return iBinder;
        }
    
        private IBinder iBinder = new IImoocAIDL.Stub() {
            @Override
            public int add(int num1, int num2) throws RemoteException {
                Log.e(TAG,"收到了来自客户端的请求" + num1 + "+" + num2 );
                return num1 + num2;
            }
    
        };
    }
    

    //AndroidManifest.xml

    <application
    	...
    		<service android:name=".IRemoteService"
                android:process=":remote"
                android:exported="true">
                <intent-filter>
                    <action android:name="com.example.administrator.aidl_server"/>
                </intent-filter>
            </service>
    	...
    </application>
    

    Aidl_Client端###

    com.example.administrator.aidl_client.MainActivity
    public class MainActivity extends AppCompatActivity {
        public static final String TAG = "MainActivity";
        private EditText et_send_input,nub_1,nub_2;
        private TextView tv_send;
        private TextView tv_bind;
        private IImoocAIDL iImoocAIDLService;
    
        private ServiceConnection conn = new ServiceConnection() {
    
            //绑定服务,回调onBind()方法
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                iImoocAIDLService = IImoocAIDL.Stub.asInterface(service);
            }
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
                iImoocAIDLService = null;
            }
        };
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            bindService();
    
            et_send_input = findViewById(R.id.et_send_input);
            nub_1 = findViewById(R.id.nub_1);
            nub_2 = findViewById(R.id.nub_2);
            tv_send = findViewById(R.id.tv_send);
            tv_bind = findViewById(R.id.tv_bind);
    
            tv_send.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    try {
                        int nub1 = Integer.parseInt(nub_1.getText().toString().trim());
                        int nub2 = Integer.parseInt(nub_2.getText().toString().trim());
    
                        int result = iImoocAIDLService.add(nub1,nub2);
                        et_send_input.setText(result+"");
                    }catch (Exception e){
                        e.printStackTrace();
                    }
    
                }
            });
    
            tv_bind.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    bindService();
                    Log.e(TAG,"bindService"+iImoocAIDLService);
                }
            });
        }
    
        private void bindService() {
            Intent intent = new Intent();
            //绑定服务端的service
            intent.setAction("com.example.administrator.aidl_server.IRemoteService");
            //新版本(5.0后)必须显式intent启动 绑定服务
            intent.setComponent(new ComponentName("com.example.administrator.aidl_server","com.example.administrator.aidl_server.IRemoteService"));
            //绑定的时候服务端自动创建
            bindService(intent,conn, Context.BIND_AUTO_CREATE);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unbindService(conn);
        }
    }
    

    layout/activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <LinearLayout
            android:gravity="center"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
    
            <EditText
                android:id="@+id/nub_1"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:inputType="number" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="+" />
    
            <EditText
                android:id="@+id/nub_2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:inputType="number" />
    
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="=" />
    
            <EditText
                android:id="@+id/et_send_input"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:inputType="number" />
        </LinearLayout>
    
        <TextView
            android:id="@+id/tv_bind"
            android:layout_width="200dp"
            android:layout_height="55dp"
            android:layout_gravity="center"
            android:layout_marginBottom="15dp"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="bind" />
    
        <TextView
            android:id="@+id/tv_send"
            android:layout_width="200dp"
            android:layout_height="55dp"
            android:layout_gravity="center"
            android:background="@color/colorAccent"
            android:gravity="center"
            android:text="计算" />
    
    
    </LinearLayout>
    

    三.注意事项##

    如果运行中报错:

    aidl Method threw 'java.lang.SecurityException' exception.

    需要 确保客户端的aidl文件包名要与服务端的包名一样.也就是本项目中的IImoocAIDL.aidl文件包名一致.


    [1] 参考资料: https://blog.csdn.net/jinxinliu1/article/details/70174591

  • 相关阅读:
    (转)关于c#中的事件
    MySql数据库--持续记录ing
    在Eclipse中通过JDBC连接MySQL步骤,非常详细!
    mybatis传入参数类型parameterType和输出结果类型resultType详解
    关于JDBC访问存储过程的问题
    Mybatis(一)入门
    [Redis] 基于redis的分布式锁
    分布式锁----浅析redis实现
    MyBatis的增删改查操作
    C3P0连接池工具类实现步骤及方法
  • 原文地址:https://www.cnblogs.com/bugzone/p/aidl.html
Copyright © 2020-2023  润新知