zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    CodeForces Gym 100935G Board Game DFS
    CodeForces 493D Vasya and Chess 简单博弈
    CodeForces Gym 100935D Enormous Carpet 快速幂取模
    CodeForces Gym 100935E Pairs
    CodeForces Gym 100935C OCR (水
    CodeForces Gym 100935B Weird Cryptography
    HDU-敌兵布阵
    HDU-Minimum Inversion Number(最小逆序数)
    七月馒头
    非常可乐
  • 原文地址:https://www.cnblogs.com/bugzone/p/aidl.html
Copyright © 2011-2022 走看看