美文网首页
Android AIDL详解

Android AIDL详解

作者: 郑在学_blog | 来源:发表于2017-10-05 12:43 被阅读0次

    什么是AIDL?

    AIDL:它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口。

    为什么会出现AIDL?

    AIDL是处理多线程,多CLIENT并发访问的跨进程通讯技术。
    Messager也可以跨进程通讯,但它是单线程的。
    广播也可以跨进程通讯,但是它不能长时间建立联系,再OnReicever()中不能执行耗时工作,会造成ANR,而AIDL因为绑定了Service所以可以执行耗时的工作。
    Handler是负责进程里不同线程之间的通信。
    contentProvider只是将接口暴露出去给其他进程调用。数据不是实时的。

    AIDL的使用

    在android studio里面使用AIDL,因为是两个进程间交互么,所以需要两个APP,我们在第一个工程目录右键新建一个AIDL文件。


    输入名称后,sutido就帮我们创建了一个AIDL文件。

    // IMyAidlInterface.aidl
    package cc.abto.demo;
    
    // Declare any non-default types here with import statements
    
    interface IMyAidlInterface {
        /**
         * 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);
    }
    

    上面就是studio帮我生成的aidl文件。basicTypes这个方法可以无视,看注解知道这个方法只是告诉你在AIDL中你可以使用的基本类型(int, long, boolean, float, double, String),因为这里是要跨进程通讯的,所以不是随便你自己定义的一个类型就可以在AIDL使用的,这些后面会说。我们在AIDL文件中定义一个我们要提供给第二个APP使用的接口。

    interface IMyAidlInterface {
       String getName();
    }
    

    定义好之后,就可以sycn project一下,然后新建一个service。在service里面创建一个内部类,继承你刚才创建的AIDL的名称里的Stub类,并实现接口方法,在onBind返回内部类的实例。

    public class MyService extends Service
    {
    
        public MyService()
        {
    
        }
    
        @Override
        public IBinder onBind(Intent intent)
        {
            return new MyBinder();
        }
    
        class MyBinder extends IMyAidlInterface.Stub
        {
    
            @Override
            public String getName() throws RemoteException
            {
                return "test";
            }
        }
    }
    
    

    接下来,将我们的AIDL文件拷贝到第二个项目,然后sycn project一下工程。

    这边的包名要跟第一个项目的一样哦,这之后在Activity中绑定服务。

    public class MainActivity extends AppCompatActivity
    {
    
    
        private IMyAidlInterface iMyAidlInterface;
    
        @Override
        protected void onCreate(Bundle savedInstanceState)
        {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bindService(new Intent("cc.abto.server"), new ServiceConnection()
            {
    
                @Override
                public void onServiceConnected(ComponentName name, IBinder service)
                {
    
                    iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
                }
    
                @Override
                public void onServiceDisconnected(ComponentName name)
                {
    
                }
            }, BIND_AUTO_CREATE);
        }
    
        public void onClick(View view)
        {
            try
            {
                Toast.makeText(MainActivity.this, iMyAidlInterface.getName(), Toast.LENGTH_SHORT).show();
            }
            catch (RemoteException e)
            {
                e.printStackTrace();
            }
        }
    }
    

    这边我们通过隐式意图来绑定service,在onServiceConnected方法中通过IMyAidlInterface.Stub.asInterface(service)获取iMyAidlInterface对象,然后在onClick中调用iMyAidlInterface.getName()。

    在AIDL中使用自定义类型

    如果我要在AIDL中使用自定义的类型,要怎么做呢。首先我们的自定义类型要实现Parcelable接口,下面的代码中创建了一个User类并实现Parcelable接口。这边就不对Parcelable进行介绍了,不熟悉的童鞋自行查找资料。

    接下新建一个aidl文件,名称为我们自定义类型的名称,这边是User.aidl。在User.aidl申明我们的自定义类型和它的完整包名,注意这边parcelable是小写的,不是Parcelable接口,一个自定类型需要一个这样同名的AIDL文件。

    package cc.abto.demo;
    parcelable User;
    

    然后再在我们的AIDL接口中导入我们的AIDL类型。


    然后定义接口方法,sycn project后就可以在service中做具体实现了。

    public class MyService extends Service
    {
        //...
        @Override
        public IBinder onBind(Intent intent)
        {
            return new MyBinder();
        }
    
        class MyBinder extends IMyAidlInterface.Stub
        {
            //...
            @Override
            public User getUserName() throws RemoteException
            {
                return new User("wswf");
            }
        }
    }
    
    

    最后将我们的AIDL文件和自定义类型的java一并拷贝到第二个项目,注意包名都要一样哦


    然后就可以在Activity中使用该自定义类型的AIDL接口了

    public class MainActivity extends AppCompatActivity
    {
        //...
        public void onClick(View view)
        {
            try
            {
                Toast.makeText(MainActivity.this, iMyAidlInterface.getUserName().getName(), Toast.LENGTH_SHORT).show();
            }
            catch (RemoteException e)
            {
                e.printStackTrace();
            }
        }
    }
    
    
    

    参考文章:
    Android中AIDL的使用详解 http://www.jianshu.com/p/d1fac6ccee98
    彻底明确Android中AIDL及其使用 http://www.cnblogs.com/tlnshuju/p/6791204.html

    相关文章

      网友评论

          本文标题:Android AIDL详解

          本文链接:https://www.haomeiwen.com/subject/ggbhyxtx.html