Android Studio 創建AIDL Service

前言

想想一下這樣一種場景,我們在模塊化開發某個功能的時候,我們不想吧核心的代碼曝露出去,而且也沒辦法曝露出某些代碼。例如:某第三方要提供給一些功能給外部。在比如,上層APP的開發者需要用到某手機專屬的某一功能A,但該手機廠商又沒有對外發布sdk(或者jar包)。本文介紹的AIDL機制理論上可以解決該問題。

創建Android Studio Project

這裏不描述是如何step by step創建 project,最終結果如下圖所示。其中aidl 是module名稱,在下一節介紹
創建Android Studio Project

創建AIDL module

File New module
對應的module創建成功之後,創建一個AIDL文件,一個service文件;在service文件中實現AIDL的接口調用
這裏寫圖片描述
IMyAidlInterface.aidl

// IMyAidlInterface.aidl
package cp.com.aidl;

// 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.
     */
    String getStr();
    boolean setStatus(int aInt);
}

MyAIDLService.java

package cp.com.aidl;

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


public class MyAIDLService extends Service {
    private  static  final String TAG=MyAIDLService.class.getSimpleName();

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        //throw new UnsupportedOperationException("Not yet implemented");
        return  mBinder;
    }

    private final IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {
        @Override
        public String getStr() throws RemoteException {
            Log.e(TAG,"this from AIDL service ...getStr..");
            return TAG;
        }

        @Override
        public boolean setStatus(int aInt) throws RemoteException {
            Log.e(TAG,"this from AIDL service ...setStatus..="+aInt);
            return (aInt%2 == 0);
        }
    };
}

需要注意的一點是,在實現module的aidl代碼時,完成aidl代碼的編寫之後需要講module build下。否則可能會出現找不到包名的情況。
好,至此我們講AIDL的實現部分使用Android studio 的module來實現;接下來我們在app中來調用對應的服務。

客戶端調用AIDL服務

創建客戶端aidl文件

首先在/path/to/application/app/src/main目錄下創建一個aidl目錄(名字任意)
接着創建一個同.aidl文件相同的包名,並將aidl文件拷貝到該包名下;例如這裏的cp.com.aidl
這裏寫圖片描述

綁定service

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Intent intent = new Intent();
        intent.setClass(getApplicationContext(), MyAIDLService.class);
        bindService(intent,conn,Service.BIND_AUTO_CREATE);
    }

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mAIDLService = IMyAidlInterface.Stub.asInterface(service);
        }

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

    private void updateTextView(){
        String str = null;
        boolean status = false;
        try {
            str = mAIDLService.getStr();
            status = mAIDLService.setStatus(count);
            count++;
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        aidlTextView.setText(str+status);
    }

確認APP同 module的依賴關係

這裏寫圖片描述

編譯運行

這裏寫圖片描述

後話

IPC用處還是多多的。。
後續,當有某一功能即是必須要曝露給第三方,但是又不能給核心代碼,編譯jar包扔進APP又太繁瑣。這裏提供了一個可選擇的方案

發佈了75 篇原創文章 · 獲贊 34 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章