1. 程式人生 > >android程序間通訊AIDL的簡單實現。

android程序間通訊AIDL的簡單實現。

aidl程序間通訊,肯定是兩個程序之間了,我們可以簡單的將其分為服務端和客戶端,客戶端負責發起一個求和的請求,服務端則負責執行這個求和的動作並將求和的結果返回給客戶端。

先看看服務端的程式碼建立吧,用的開發工具是AndroidStudio,右鍵新建aidl檔案,程式碼如下

interface AIDLTest {
    /**
     * 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);
}
有個基礎型別的引數說明,不包含short型別,其他的都是支援的,基礎型別外,String型別也是支援的。我查了資料發現,還有charsequence和parcelable也是支援的。

aidl檔案寫完後需要編譯一下AndroidStudio,不然拿不到aidl的引用。服務端一般就是一個Service,在onBind方法中返回一個aidl 的stub物件,然後會重寫一個aidl介面中的方法,

具體的業務操作就在這裡面實現了,下面貼上程式碼,由於比較簡單,所以程式碼很少。

package company.huawei.com.aidltest;

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

/**
 * Created by n911970 on 2017/7/27.
 */

public class AIDLService extends Service
{
    
    private IBinder iBinder = new IMyAidlInterface.Stub()
    {
        @Override
        public int getSum(int num1, int num2) throws RemoteException
        {
            Log.d("AIDLService","num1 = "+num1 +",num2 =" +num2);
            return num1 + num2;
        }
    };
    
    @Override
    public IBinder onBind(Intent intent)
    {
        return iBinder;
    }
}
注意Service需要在Manifest中註冊,exported屬性需要置為true
   <service
            android:name=".AIDLService"
            android:enabled="true"
            android:exported="true">

   </service>
下面看下客戶端的程式碼,主要就是繫結服務端的這個Service然後獲取IBinder物件,然後進行求和的請求操作。客戶端也需要寫一個aidl檔案,必須和服務端的完全一致,包括包名和aidl檔名,不然會報錯。如下圖所示


下面看下客戶端的程式碼吧,寫了個Buttton,點選這個button進行求和的操作,然後在服務端打了log,客戶端彈出toast,已親自試驗過是可以的了。

直接上程式碼吧,有簡單的註釋。

package company.huawei.com.aidlclient;

import company.huawei.com.aidltest.IMyAidlInterface;

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

public class MainActivity extends Activity {

    private static final String TAG = "MainActivity";
    private IMyAidlInterface aidl;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {

            Log.d(TAG,"---onServiceConnected---");
            aidl = IMyAidlInterface.Stub.asInterface(iBinder);

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

            aidl = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                try {
                    getSum(2, 4);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        });
        bindService();
    }


    /**
     * 繫結service
     */
    private void bindService() {
        Intent intent = new Intent();
        //注意必須為顯式的方式去啟動這個service
        intent.setComponent(new ComponentName("company.huawei.com.aidltest", "company.huawei.com.aidltest.AIDLService"));
        bindService(intent, conn, Context.BIND_AUTO_CREATE);
    }

    /**
     * 求和操作
     *
     * @param a 引數1
     * @param b 引數2
     */
    private void getSum(int a, int b) throws RemoteException {
        int sum = aidl.getSum(a, b);
        Log.d(TAG, "sum = " + sum);
        Toast.makeText(MainActivity.this, "求和後的結果為:" + sum, Toast.LENGTH_LONG).show();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //頁面銷燬記得解綁service
        unbindService(conn);
    }
}