1. 程式人生 > >AIDL使用詳解(三) 客戶端通過AIDL與服務端通訊 例項專案

AIDL使用詳解(三) 客戶端通過AIDL與服務端通訊 例項專案

專案簡介

我們要實現一個計算器的功能。
首先實現一個服務端,用於提供計算服務,供客戶端去呼叫。它接受客戶端提供的兩個值,計算之後,返回兩個數之和。
這裡寫圖片描述
第二,實現客戶端介面進行操作。

這裡寫圖片描述

第三: 我們命名客戶端和服務端。

第四:定義AIDL,連線客戶端與服務端。

這裡寫圖片描述

程式程式碼

實現服務端

1. 定義aidl介面

// IMyAidlInterface.aidl
package com.kite.aidltest;

// Declare any non-default types here with import statements

interface IMyAidlInterface
{
//計算兩個數之和 int add(int num1, int num2); }

修改之後,編譯一下,Build ->make project.

根據官方文件:
這裡寫圖片描述

2. 實現介面

我們定義好adil檔案後,然後實現該介面。接下來建立一個service去實現服務端。

這裡寫圖片描述

package com.kite.aidltest;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import
android.util.Log; public class RemoteService extends Service { private static final String TAG = "RemoteService"; public RemoteService() { } /** * 當客戶端繫結該服務時 會執行以下程式碼,返回iBInder物件 * @param intent * @return */ @Override public IBinder onBind(Intent intent) { return
iBinder; } private IBinder iBinder = new IMyAidlInterface.Stub() { @Override public int add(int num1, int num2) throws RemoteException { Log.d(TAG, "add方法:收到了客戶端的請求 ,輸入的" + "num1 ->" + num1 + "\n num2 ->" + num2); return num1 + num2; } }; }

3. 向客戶端公開該介面

這也是實現客戶端的步驟,請見實現客戶端

實現客戶端

新建aidl client 模組

新建一個aidl client 模組。詳細步驟如圖:

這裡寫圖片描述

這裡寫圖片描述

這裡寫圖片描述

建立介面

修改該模組的activity_main 資原始檔。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main"
    android:layout_width="match_parent" android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    tools:context="com.kite.aidlclient.MainActivity">

   <EditText
       android:id="@+id/num1"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:background="#ececec"/>

    <TextView
        android:id="@+id/add"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="+" />
    <EditText
        android:id="@+id/num2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#ececec"/>

    <TextView
        android:id="@+id/value"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="25sp"
        android:text="=" />

    <EditText
        android:id="@+id/result"
        android:inputType="none"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#eceaea"/>

    <Button
        android:id="@+id/toAdd"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:text="哆啦A夢超能力(計算)"/>
</LinearLayout>

注意:客戶端和服務端的adil檔案必須一致(包名也必須一致),所以複製服務端的adil檔案到adilclient中,然後編譯程式。
然後修改 MainActivity

package com.kite.aidlclient;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;

import com.kite.aidltest.IMyAidlInterface;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final String TAG = "MainActivity";

    private EditText num1;
    private EditText num2;
    private EditText result;

    private Button toAdd;

    IMyAidlInterface iMyAidlInterface;

    private ServiceConnection conn = new ServiceConnection() {
        //繫結上服務的時候
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            //接受到了遠端的服務
            Log.d(TAG, "onServiceConnected: ");
            iMyAidlInterface = IMyAidlInterface.Stub.asInterface(iBinder);

        }

        // 當服務斷開的時候呼叫
        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            Log.d(TAG, "onServiceDisconnected: ");
            //回收資源
            iMyAidlInterface = null;

        }
    };

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

        initView();

        bindServce();
    }

    private void initView() {
        num1 = (EditText) findViewById(R.id.num1);
        num2 = (EditText) findViewById(R.id.num2);
        result = (EditText) findViewById(R.id.result);

        toAdd = (Button) findViewById(R.id.toAdd);
        toAdd.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int number1 = Integer.valueOf(num1.getText().toString());
        int number2 = Integer.valueOf(num2.getText().toString());

        try {
            //呼叫遠端服務
            int valueRes = iMyAidlInterface.add(number1, number2);
            result.setText(valueRes + "");
        } catch (RemoteException e) {
            e.printStackTrace();
            result.setText("error");
        }


    }

    private void bindServce() {
        //獲取到服務端, 5.0 之後必須顯示繫結服務
        Intent intent = new Intent();
        intent.setComponent(new ComponentName("com.kite.aidltest", "com.kite.aidltest.RemoteService"));
        bindService(intent, conn, BIND_AUTO_CREATE);
        Log.d(TAG, "bindServce: bind on end");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }
}

注意事項

  1. 每次修改aidl檔案都要編譯一下程式。
  2. 兩個模組都要安裝在手機中,並且開啟。這樣才能呼叫服務端。