1. 程式人生 > >第18天Service-AIDL程序間通訊

第18天Service-AIDL程序間通訊

第18天Service-AIDL程序間通訊

AIDL

一.AIDL簡介

AIDL,全稱是Android Interface Define Language,即安卓介面定義語言,可以實現安卓裝置中程序之間的通訊(Inter Process Communication, IPC)。安卓中的服務分為2類:本地服務(網路下載大檔案,音樂播放器,後臺初始化資料庫的操作);遠端服務(遠端呼叫支付寶程序的服務。。)

二.AIDL的使用

假設有如下場景,需要計算a+b的值,在客戶端中獲取a和b的值,然後傳遞給服務端,服務端進行a+b的計算,並將計算結果返回給客戶端。
這裡的客戶端和服務端均是指安卓裝置中的應用,由於每一個應用對應一個程序,由此可以模擬安卓系統中通過AIDL進行程序之間的通訊。

三 .使用步驟

服務端moudle:aidl_server

(1)將as切換到Project下,按照如圖所示建立資料夾命名為aidl,在aidl資料夾下建立aidl檔案,命名為IMyAidlInterface.aidl
在這裡插入圖片描述
在這裡插入圖片描述
(2)修改aidl檔案,提供一個方法,該方法 就是處理客戶端的請求
在這裡插入圖片描述
(3)rebuild project之後會發現自動生成一個Java檔案:IMyAidlInterface.java
在這裡插入圖片描述


(4)在服務端中新建一個類,繼承Service,在其中定義一個IBinder型別的變數iBinder,引用上述介面IMyAidlInterface.java類中的Stub類物件,實現其中的add方法,在Service的onBind方法中,返回iBinder變數。最終程式碼如下:

public class ServerService extends Service {
    //TODO 代理人
    IBinder binder=new IMyAidlInterface.Stub() {
        @Override
        public int add(int num1,
int num2) throws RemoteException { return num1+num2; } }; @Nullable @Override public IBinder onBind(Intent intent) { return binder; } }

(5)清單檔案中註冊SErverService服務,在註冊時應設定exported屬性為true,保證該Service能被其他應用呼叫,否則會報
java.lang.SecurityException: Not allowed to bind to service Intent 異常。
在這裡插入圖片描述

OK,服務端的服務已經配置完畢

客戶端moudle:aidl_client

(1)在客戶端建立同樣AIDL檔案,要求包名AIDL名字必須一致,內容也必須一樣提供add方法,rebuild 專案
在這裡插入圖片描述
(2)Java程式碼,繫結服務呼叫伺服器程序的方法

public class MainActivity extends AppCompatActivity {
    IMyAidlInterface iMyAidlInterface;
    //3.繫結服務回撥
    private ServiceConnection connection=new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            //繫結服務成功後,返回服務端返回的binder,將其轉成IMyAidlInterface呼叫add方法
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
            try {
                int num=iMyAidlInterface.add(4,6);//呼叫服務端的add方法並得到結果
                Toast.makeText(MainActivity.this, ""+num, Toast.LENGTH_SHORT).show();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        @Override
        public void onServiceDisconnected(ComponentName name) {
            //解除繫結時呼叫, 清空介面,防止內容溢位
            iMyAidlInterface=null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1.繫結服務
        Intent intent=new Intent();
        intent.setAction("com.bawei.1609A");//設定action
        intent.setPackage("com.example.aidl_server");//設定服務端應用程序包名
        bindService(intent,connection, Service.BIND_AUTO_CREATE);
    }
    //2.解除繫結
    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(connection);
    }
}

注意:先啟動服務端,在啟動客戶端

總結:

服務端:建立aidl檔案並編輯提供方法–》rebuild—>建立服務,onbind方法中返回一個binder物件—》註冊服務
客戶端:建立aidl檔案和服務端一模一樣–》rebuild–〉繫結服務呼叫方法