Android中AIDL的使用詳解

為了說的深入淺出一點(diǎn),我們先從AIDL的作用和使用說起,然后再開始介紹一些概念和工作原理。

AIDL用來做什么

AIDL是Android中IPC(Inter-Process Communication)方式中的一種,AIDL是Android Interface definition language的縮寫,對(duì)于小白來說,AIDL的作用是讓你可以在自己的APP里綁定一個(gè)其他APP的service,這樣你的APP可以和其他APP交互。

AIDL的使用

在android studio 2.0里面使用AIDL,因?yàn)槭莾蓚€(gè)APP交互么,所以當(dāng)然要兩個(gè)APP啦,我們?cè)诘谝粋€(gè)工程目錄右鍵



輸入名稱后,sutido就幫我們創(chuàng)建了一個(gè)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這個(gè)方法可以無視,看注解知道這個(gè)方法只是告訴你在AIDL中你可以使用的基本類型(int, long, boolean, float, double, String),因?yàn)檫@里是要跨進(jìn)程通訊的,所以不是隨便你自己定義的一個(gè)類型就可以在AIDL使用的,這些后面會(huì)說。我們?cè)贏IDL文件中定義一個(gè)我們要提供給第二個(gè)APP使用的接口。

interface IMyAidlInterface {
   String getName();
}

定義好之后,就可以sync project一下,然后新建一個(gè)service。在service里面創(chuàng)建一個(gè)內(nèi)部類,繼承你剛才創(chuàng)建的AIDL的名稱里的Stub類,并實(shí)現(xiàn)接口方法,在onBind返回內(nèi)部類的實(shí)例。

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文件拷貝到第二個(gè)項(xiàng)目,然后sync project一下工程。


這邊的包名要跟第一個(gè)項(xiàng)目的一樣哦,這之后在Activity中綁定服務(wù)。

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對(duì)象,然后在onClick中調(diào)用iMyAidlInterface.getName()。

自定義類型

如果我要在AIDL中使用自定義的類型,要怎么做呢。首先我們的自定義類型要實(shí)現(xiàn)Parcelable接口,下面的代碼中創(chuàng)建了一個(gè)User類并實(shí)現(xiàn)Parcelable接口。這邊就不對(duì)Parcelable進(jìn)行介紹了,不熟悉的童鞋自行查找資料,總之我們這邊可以借助studio的Show Intention Action(也就是Eclipse中的Quick Fix,默認(rèn)是alt+enter鍵)幫我們快速實(shí)現(xiàn)Parcelable接口。


接下新建一個(gè)aidl文件,名稱為我們自定義類型的名稱,這邊是User.aidl。在User.aidl申明我們的自定義類型和它的完整包名,注意這邊parcelable是小寫的,不是Parcelable接口,一個(gè)自定類型需要一個(gè)這樣同名的AIDL文件。

package cc.abto.demo;
parcelable User;

然后再在我們的AIDL接口中導(dǎo)入我們的AIDL類型。


然后定義接口方法,sync project后就可以在service中做具體實(shí)現(xiàn)了。

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一并拷貝到第二個(gè)項(xiàng)目,注意包名都要一樣哦



然后就可以在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();
        }
    }
}

效果圖就不貼了哈,通過這種方式我們就可以讓兩個(gè)APP之間進(jìn)行交互了。

最后

為什么APP間的進(jìn)程交互這么麻煩,是因?yàn)樗鼈儗儆诓煌倪M(jìn)程,之間的交互涉及到進(jìn)程間的通訊。而AIDL只是Android中眾多進(jìn)程間通訊方式中的一種方式,那么AIDL到底是什么鬼,它是如何工作的,Android的IPC機(jī)制又是怎樣的呢。我將在下一篇文章Android中AIDL的工作原理中介紹。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容