1. 程式人生 > >Android Studio中AIDL使用方法

Android Studio中AIDL使用方法

一、簡介:
AIDL:Android Interface Define Language(Android介面定義語言),主要用於服務端與客戶端程序間通訊(服務端與多客戶端)

二、配置
Android Studio中使用(最好採用project模式)
1、第一類:
簡單資料傳遞(基本資料型別,String ,List,Map)

<1>服務端配置(不需要介面)

①.建立aidl自定義介面檔案 —IMyAidlInterface.aidl

步驟:File –> New –> AIDL –> AIDL File

然後可以看到在src/main目錄下生成了一個目錄aidl,點開aidl,可以看到剛才建立的IMyAidlInterface.aidl檔案
這裡寫圖片描述


IMyAidlInterface.aidl程式碼如下:

package com.example.lambert.aidltest;

interface IMyAidlInterface {

    String getValue();

}

②編譯(因為Android Studio不能像Eclipse那樣自動編譯aidl檔案,所以需要手動編譯)
點選Build –> Make Module’server’
然後可以看到在build/generated/source/debug/com.example.lambert.aidlproject/目錄下生成了一個檔案IMyAidlInterface,表示編譯成功;
這裡寫圖片描述

③編寫Service

package com.example.lambert.aidltest;

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

public class MyService extends Service {
    @Override
    public IBinder onBind(Intent intent) {

        //記得要return一個IMyService,否則客戶端呼叫的時候會報空指標
return new IMyService(); } public class IMyService extends IMyAidlInterface.Stub { @Override public String getValue() throws RemoteException { return "This is Lambert Server"; } } }

④在AndroidMenifest.xml中對Service進行配置:

 <!-- MyService -->
        <service
            android:name=".MyService"
            android:process=":remote">
            <intent-filter>
                <action android:name="com.example.lambert.aidlproject.MyService" />
            </intent-filter>
        </service>

到此為止,服務端配置完畢。

<2>客戶端配置

①需要將服務端配置的整個aidl目錄一併拷貝到客戶端所在工程src/main目錄下(包名與檔名必須與服務端一模一樣)
這裡寫圖片描述

②編譯(同服務端)

這裡寫圖片描述

③繫結服務

MainActivity.java

package com.example.lambert.client;

import android.app.Activity;
import android.content.ComponentName;
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.TextView;

import com.example.lambert.aidlproject.IMyAidlInterface;
import com.example.lambert.aidlproject.Person;

public class MainActivity extends Activity implements View.OnClickListener {
    private IMyAidlInterface mService;
    private Button btn_bind, btn_get;
    private TextView tv;
    private ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mService = IMyAidlInterface.Stub.asInterface(service);
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            mService = null;
        }
    };

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

    private void init() {
        btn_bind = (Button) findViewById(R.id.btn_bind);
        btn_get = (Button) findViewById(R.id.btn_get);
        tv = (TextView) findViewById(R.id.tv);

        btn_bind.setOnClickListener(this);
        btn_get.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_bind:
                Intent intent = new Intent();
                intent.setAction("com.example.lambert.aidlproject.MyService");
                //從 Android 5.0開始 隱式Intent繫結服務的方式已不能使用,所以這裡需要設定Service所在服務端的包名
                intent.setPackage("com.example.lambert.aidlproject");
                bindService(intent, connection, Context.BIND_AUTO_CREATE);
                break;
            case R.id.btn_get:
                try {
                    String str = mService.getValue();
                    tv.setText(str);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (serviceConnection != null) {
            unbindService(connection);
        }
    }

}

通過 mService = IMyAidlInterface.Stub.asInterface(service); 可以獲取到服務端的代理物件,從而可以通過回撥方法從服務端獲取到我們所需的資料。

2.第二類:自定義複雜資料型別(Parcelable)

<1>服務端配置(不需要介面)

①.在上述aidl目錄下建立複雜資料物件aidl檔案(這裡以Person.aidl為例)對複雜物件進行宣告:

這裡寫圖片描述

Person.aidl

// Person.aidl
package com.example.lambert.aidlproject;
parcelable Person;

②在src/main/java目錄下建立Person.java檔案

這裡寫圖片描述

Person.java

package com.example.lambert.aidlproject;

import android.os.Parcel;
import android.os.Parcelable;

public class Person implements Parcelable {
    public static final Creator<Person> CREATOR = new Creator<Person>() {
        @Override
        public Person createFromParcel(Parcel in) {
            return new Person(in);
        }

        @Override
        public Person[] newArray(int size) {
            return new Person[size];
        }
    };
    private String name;

    public Person(String name) {
        this.name = name;
    }

    protected Person(Parcel in) {
        name = in.readString();
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(name);
    }

}

③修改IMyAidlInterface.aidl如下:

package com.example.lambert.aidlproject;
//PS:這裡需要注意import匯入Person,第一類不需要匯入
import com.example.lambert.aidlproject.Person;

interface IMyAidlInterface {

    Person getValue();

}

④Service類也做出相應修改

    public class IMyService extends IMyAidlInterface.Stub {

        @Override
        public Person getValue() throws RemoteException {
            return new Person("Rose");
        }
    }

}

⑤編譯(同上)

到此為止,服務端配置完畢。

<2>客戶端配置
①拷貝Person.aidl和Person.java檔案到客戶端工程下:

Person.aidl可以拷貝到aidl目錄下:
這裡寫圖片描述

Person.java檔案需要拷貝到src/main/java目錄下,並且所在包名必須與服務端保持一致,但是客戶端工程包名與服務端包名未必一致,所以在這裡我們需要重新建立一個包com.example.lambert.aidlproject(服務端工程包名),並將Person.java檔案拷貝至此;
這裡寫圖片描述

另:IMyAidlInterface.aidl做同上修改,當然也可以直接拷貝過來

②編譯(同上)
③MainActivity程式碼也做相應修改

  try {
                    Person person = mService.getValue();
                    tv.setText(person.toString());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }

客戶端配置完畢。

關於AIDL在Android Studio中的使用暫且簡單介紹到這裡。