Android進程間通信IPC詳解

最近項目有進程間通信的需求,我使用的是IPC通信的方式,這是Android中很傳統的一種進程間通信的方式,在這里分享給大家。

進程間通信意義

我們為什么要使用進程間通信。我說一個場景,比如我們有兩個App,其中一個App(名字為A),有授權登陸,我們還有一個App(名字為B)可能是A的附屬App,或者同期產品,我們希望有相同的賬號,也就是A登陸了,B就自動登錄了。那么B在進入的時候需要從A中拿登陸信息,比如姓名性別,昵稱等。這時候就涉及到進程間通信了。或者B中需要一些加密算法,我們不想在B中暴露,可以把值傳給A,然后A計算完再傳遞回來。

當然還有其它場景,這里不再贅述了。

建立個工程

首先我們當然要建立一個工程,最普通的工程就可以。

服務端App

這個工程中的第一個module服務端module,也就是上面提到的A app,內容提供的app

我們在src/main中建立一個aidl文件夾:

右鍵點擊aidl文件夾,new一個aidl文件:

在里面建立一個文件,比如我們想獲取用戶信息:

interface IPeople {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
     String getName();
     String getSex();
}

然后rebuild一下工程,這時,會在build文件夾下生成一個文件

這個文件就是aidl生成的對應的接口文件,沒有這個文件,我們之后在引用接口的時候會報錯。你不用給它轉移地方,放在這就行了。

然后我們寫一個服務Service,提供數據:

public class AidlService extends Service{
    private PeopleBinder peopleBinder;
    @Override
    public void onCreate() {
        super.onCreate();
            peopleBinder = new  PeopleBinder();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return peopleBinder;
    }

    public class PeopleBinder extends IPeople.Stub
    {


        @Override
        public String getName() throws RemoteException {
            return "deep";
        }

        @Override
        public String getSex() throws RemoteException {
            return "man";
        }
    }
}

其中PeopleBinder是進程間傳遞數據的媒介,如果你想傳一個數據類,那么這個數據類一定要序列化。PeopleBinder實現的接口,就是剛才我們生成的那個文件中的接口。所以一定要等aidl接口文件生成我們再去寫這個類。

然后將Service注冊在AndroidManifest中,注意要加一個action,方便客戶端App啟動:

<service android:name=".AidlService">
            <intent-filter>
                <action android:name="deep.testaidl.AidlService"/>
            </intent-filter>
        </service>

要注意app要安裝到手機上啊,否則后面怎么獲取……

客戶端App

我們新建一個module,這個module就是客戶端App,也就是我們上文中提到的B App,內容索取者。

用同樣的方式建立一個aidl文件,這個aidl文件要與上面的一樣,且路徑也要一樣,如圖所示:

可以看到路徑一樣,文件名一樣,當然內容也一樣。

這樣才能保證協議一致。然后還是rebuild一下。生成對應的接口文件。

然后我們在Activity中,隨便寫一個布局(這個不多說了,與本文主旨無關),有個按鈕,有個顯示就行。

然后開始獲取用戶資料了,首先,我們需要定義一個協議接口,也就是你獲取用戶資料的接口:

private IPeople people;//協議接口

接著需要建立一個服務連接,與服務端App剛寫的那個Service進行連接通信:

private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            people = IPeople.Stub.asInterface(service);//連接建立成功,讀取數據
            try {

               textView.setText("name ="+people.getName()+" sex="+people.getSex());
            } catch (RemoteException e) {
                e.printStackTrace();
            }

        }

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

        }
    };

剛才不是寫了一個按鈕嗎,添加一個點擊事件,打開服務端寫好的Service,進行通信:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent();
                intent.setAction("deep.testaidl.AidlService");
                intent.setPackage("deep.testaidl");
                bindService(intent,conn, Service.BIND_AUTO_CREATE);
            }
        });

由于我們剛才在服務連接的回調中,將用戶信息設置到了textview上,這樣就可以顯示出來了。

好了,這樣一次通信就完成了,是不是沒有想象的復雜。

總結

這種進程間通信的方式還是比較傳統的,用的也比較多,了解一下對于以后的學習很有幫助,如有其它問題可以關注我的公眾號留言給我,我會第一時間回復。

 

 

來自:https://juejin.im/post/58d39de6a22b9d00644eb60b

 

 本文由用戶 mloi8526 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!