日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android绑定多个aidl,android aidl 多`module`版的实现

發(fā)布時間:2025/4/16 Android 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android绑定多个aidl,android aidl 多`module`版的实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

多module版,pojo類型數(shù)據(jù)的雙向傳遞 [service client]

android中如何進行跨進程通信的?

aidl是什么?

android中如何通過aidl實現(xiàn)跨進程通信?

最簡單的aidl如何實現(xiàn)?

多module之間如何通過aidl進行通信?

單module實現(xiàn)aidl和多module實現(xiàn)aidl有何區(qū)別?

多App之間如何通過aidl進行通信?

以上這些問題,我不打算全部回答。因為我也不知道怎么回答。

關于第一個問題,和第二個問題,我相信官方文檔以及一些大神的博客已經(jīng)有了很詳盡的介紹,這里我就贅述了。

第三個問題 android中如何通過aidl實現(xiàn)跨進程通信? 這個問題,還是太寬泛了,我也不回答了。

關于 如何實現(xiàn)最簡單的aidl,請看這篇

好了,現(xiàn)在來本篇的重點 多module之間如何通過aidl進行通信?

那我們就一步步開始吧。

后面的問題呢?別急啊...慢慢來。

關于“多module之間如何通過aidl進行通信”我準備分3個小點來說明:

- 如何實現(xiàn)多`module`之間,基本類型的數(shù)據(jù)的單向傳遞 [service --> client]

- 如何實現(xiàn)多`module`之間,自定義類型的`pojo`對象的單向傳遞 [service --> client]

- 如何實現(xiàn)多`module`之間,自定義類型的`pojo`對象的雙向傳遞 [service client]

從代碼開始:

首先,我新建一個android project,由于我使用的是android studio,所以默認新建的項目就是一個安卓項目。

新建完成項目之后,默認會生成一個module名為app。

然后,我會再建兩個module,名為service和aidl。

關于如何在android studio中新建一個module,這個大家都知道的吧。其中一種方法是:[菜單欄 --> File --> New --> New Module... --> Android Liarbry ]

好了,現(xiàn)在準備工作完成了。多module已經(jīng)建立起來了。

解釋一下service是用來作為服務的,讓app去調(diào)用的。aidl是專門用來存放.aidl文件以及對應的pojo類的。

接下來,我們?nèi)崿F(xiàn)一下服務吧,不然跨進程通信是沒法建立起來的。

1.在service所在的module中,我新建一個類繼承android.app.Service,比如RemoteService。看起來差不多這個樣子:

public class RemoteService extends Service {

public RemoteService() {

}

@Override

public IBinder onBind(Intent intent) {

throw new UnsupportedOperationException("Not yet implemented");

}

}

2.現(xiàn)在我們?nèi)バ薷囊幌虑鍐挝募W孯emoteService處在一個單獨的進程。為什么要這么干?因為如果不修改,那么無論是在哪個module實現(xiàn)的Service都是在主進程的。 好了,現(xiàn)在我們看一下修改之后的當前服務所在的節(jié)點的樣子:

android:name=".RemoteService"

android:enabled="true"

android:exported="true"

android:process=":remote" />

好了,我們?yōu)閷崿F(xiàn)跨進程通信又跨出了一步。因為現(xiàn)在的確有多個進程了。而且有多個module了。

3.現(xiàn)在呢,我們就得去定義.aidl文件了。

為什么現(xiàn)在就要定義.aidl文件呢? 因為我們知道,跨進程通信本質(zhì)上是通過bindService的方法綁定一個遠程服務,以便實現(xiàn)數(shù)據(jù)的交互。而跨進程的,內(nèi)存又無法共享,可以通過已知的共享內(nèi)存IBinder去實現(xiàn)跨進程的數(shù)據(jù)交互。ps:這個解說可能存在錯誤,請大家不要深信。

4.那么,我們準備通過跨進程傳遞什么呢?假設,我現(xiàn)在想通過aidl傳遞一個500以內(nèi)的隨機數(shù)給調(diào)用者。那么,.aidl差不多長這樣的:

// RemoteBinder.aidl

package com.pythoncat.aidl;

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

interface RemoteBinder {

/**

* 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);

int getResult();

}

**注意:這個.aidl文件是在aidl所在module中定義的。**至于能不能直接在sevcie所在module中定義,我猜測也是可以的,但是沒有去驗證。放在一個單獨的module中的好處就是,以后查閱起來方便。

5.現(xiàn)在,我們定義好了RemoteBinder.aidl,然后rebuild一下工程。之后,會自動生成一些類,這些我就不去深究了,因為和主題無關。

6.rebuild完成之后,我們?nèi)ネ晟苿偛哦x的RemoteService。重寫onBind()方法。完善之后的RemoteService差不多長這樣的:

public class RemoteService extends Service {

public RemoteService() {

}

@Override

public IBinder onBind(Intent intent) {

return new MyBinder();

}

private class MyBinder extends RemoteBinder.Stub{

@Override

public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

}

@Override

public int getResult() throws RemoteException {

return new Random().nextInt(500);

}

}

}

現(xiàn)在差不多大功告成了,就等著調(diào)用者來調(diào)用了。

7.現(xiàn)在我們?nèi)pp所在module。這里面默認給我們提供了一個MainActivity。但是我不打算對它做什么。我給它改名為LauncherActivity。并且在里面添加兩個按鈕,準備讓他們分別實現(xiàn)界面的跳轉(zhuǎn)。第二個按鈕點擊之后就跳轉(zhuǎn)到AidlActivity。當然這個AidlActivity也是在app所在module的,而且是剛剛新建的。

8.在AidlActivity里面呢,我準備弄一個textview,用于顯示,將來通過aidl獲取的500以內(nèi)的隨機數(shù)。,和一個按鈕,按鈕的點擊就是觸發(fā)獲取的條件。

9.好了,UI部分算是完成了。現(xiàn)在呢,我們先讓我們的AidlActivity去綁定服務。怎么去綁定一個服務,相信大家都會的。現(xiàn)在呢,我們就來看一下,綁定服務之后,AidiActivity長什么樣子的:

public class AidlActivity extends AppCompatActivity {

private ServiceConnection mConn;

private RemoteBinder mRemoteBinder;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_aidl);

TextView tvShowResult = (TextView) findViewById(R.id.aidl_show_tv);

TextView tvParcelable = (TextView) findViewById(R.id.aidl_show_parcelable_tv);

tvParcelable.setText(getString(R.string.show_about_parcelable_service, ""));

tvShowResult.setText(getString(R.string.show_about_normal_service, ""));

Button btnExecute = (Button) findViewById(R.id.aidl_ui_btn);

btnExecute.setOnClickListener(v -> {

if (mRemoteBinder != null) {

try {

mRemoteBinder.setResult(1024);

int result = mRemoteBinder.getResult();

tvShowResult.setText(getString(R.string.show_about_normal_service, result));

LogUtils.e("aidl result===" + result);

} catch (RemoteException e) {

LogUtils.e("bind remote service fail...");

LogUtils.e(e);

}

}

});

mConn = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

mRemoteBinder = RemoteBinder.Stub.asInterface(service);

}

@Override

public void onServiceDisconnected(ComponentName name) {

mRemoteBinder = null;

}

};

bindService(new Intent(get(), RemoteService.class), mConn, Context.BIND_AUTO_CREATE);

}

public AppCompatActivity get() {

return this;

}

@Override

protected void onDestroy() {

super.onDestroy();

if (mConn != null) {

unbindService(mConn);

mConn = null;

}

}

}

需要注意的是IBinder對象的獲取方式:mRemoteBinder = RemoteBinder.Stub.asInterface(service);

ok,似乎一切已經(jīng)完成了。那么我們就跑起來吧。... 果不其然,我們從LaunchrActivity界面進到AidlActivity先,然后,我們每點一次按鈕,textview上就出現(xiàn)一個500以內(nèi)的隨機數(shù),幾乎每次都不相同。

這么看來,我們已經(jīng)實現(xiàn)了多module之間的aidl通信。

-的確,剛才已經(jīng)實現(xiàn)了。但是剛才的實現(xiàn)僅僅是數(shù)據(jù)的單向傳遞[service-->client],而且是基本類型的數(shù)據(jù)的單向傳遞。

-現(xiàn)在呢,我們開始第二小節(jié)的說明,也就是如何實現(xiàn)多module之間的pojo類型的數(shù)據(jù)的單向傳遞 [service --> client]

還是從代碼開始:

首先在aidl所在module中定義一個pojo。比如這個樣子:

public class Duck {

public String name;

public long id;

}

為什么是在aidl所在module中定義pojo,而不是service所在module? 因為,在這里定義是為了讓.aidl能夠找到對應的pojo類。

如果在其他module中定義,就要讓其他module成為當前moudle的依賴。ps:關于此段的說明,我不能保證正確性,需要通過代碼驗證。

現(xiàn)在呢,就是要讓Duck實現(xiàn)Parcelable接口。至于怎么實現(xiàn),我只說一句:android studio有相關的插件,自動生成Parcelable接口的實現(xiàn)。

然后,定義該pojo對應的.aidl文件。差不多長這樣子的:

// Duck.aidl

package com.pythoncat.aidl.bean;

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

parcelable Duck;

注意包的對應

接下來,就是定義傳輸pojo的接口方法了。比如:Duck getDuck();。那么,我們?nèi)バ陆ㄒ粋€.aidl文件,映射一個Ibinder。里面有傳輸pojo的方法。ok,定義之后的新的.aidl差不多長這樣的:

// RemoteBinder.aidl

package com.pythoncat.aidl;

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

import com.pythoncat.aidl.bean.Duck;

interface RemoteBinder {

/**

* 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);

int getResult();

Duck getDuck();

}

再次rebuild項目。

之后,會提示你報錯了。因為你的RemoteService$MyBinder不是抽象類,并且有未實現(xiàn)的方法。那么我們就去實現(xiàn)該抽象方法。實現(xiàn)之后,Mybinder差不多長這樣子:

public class MyBinder extends RemoteBinder.Stub {

private Duck duck;

private int result;

@Override

public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

}

@Override

public int getResult() throws RemoteException {

if (result == 0) {

return new Random().nextInt(500);

} else {

return this.result;

}

}

@Override

public Duck getDuck() throws RemoteException {

if (this.duck == null) {

Duck d = new Duck();

d.id = 10086;

d.name = "DuckTang";

return d;

} else {

this.duck.name = this.duck.name + "&Jerry";

return this.duck;

}

}

}

ok,我們的服務算是搞定了,接下來就是看調(diào)用者AidlActivity了。那么,我們就去調(diào)用者中添加獲取pojo對象的方法,并顯示在textview中。差不多就是這樣子的:

Duck d = mRemoteBinder.getDuck();

tvParcelable.setText(getString(R.string.show_about_parcelable_service, d.toString()));

當然我又新加了一個textview,這個也要告訴你嗎?

現(xiàn)在呢,完整的AidlActivity是這樣的:

package com.pythoncat.ipcorservice2.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.support.v7.app.AppCompatActivity;

import android.widget.Button;

import android.widget.TextView;

import com.apkfuns.logutils.LogUtils;

import com.pythoncat.aidl.RemoteBinder;

import com.pythoncat.aidl.bean.Duck;

import com.pythoncat.ipcorservice2.R;

import com.pythoncat.service.RemoteService;

public class AidlActivity extends AppCompatActivity {

private ServiceConnection mConn;

private RemoteBinder mRemoteBinder;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_aidl);

TextView tvShowResult = (TextView) findViewById(R.id.aidl_show_tv);

TextView tvParcelable = (TextView) findViewById(R.id.aidl_show_parcelable_tv);

tvParcelable.setText(getString(R.string.show_about_parcelable_service, ""));

tvShowResult.setText(getString(R.string.show_about_normal_service, ""));

Button btnExecute = (Button) findViewById(R.id.aidl_ui_btn);

btnExecute.setOnClickListener(v -> {

if (mRemoteBinder != null) {

try {

int result = mRemoteBinder.getResult();

tvShowResult.setText(getString(R.string.show_about_normal_service, result));

LogUtils.e("aidl result===" + result);

Duck d = mRemoteBinder.getDuck();

tvParcelable.setText(getString(R.string.show_about_parcelable_service, d.toString()));

LogUtils.e("aidl parcelable===" + d.toString());

} catch (RemoteException e) {

LogUtils.e("bind remote service fail...");

LogUtils.e(e);

}

}

});

mConn = new ServiceConnection() {

@Override

public void onServiceConnected(ComponentName name, IBinder service) {

mRemoteBinder = RemoteBinder.Stub.asInterface(service);

}

@Override

public void onServiceDisconnected(ComponentName name) {

mRemoteBinder = null;

}

};

bindService(new Intent(get(), RemoteService.class), mConn, Context.BIND_AUTO_CREATE);

}

public AppCompatActivity get() {

return this;

}

@Override

protected void onDestroy() {

super.onDestroy();

if (mConn != null) {

unbindService(mConn);

mConn = null;

}

}

}

似乎已經(jīng)結(jié)束了,那就跑起來吧。run app...。果不其然,我們的界面上看到了在Mybinder中定義的new Duck()對象。

現(xiàn)在,我們就完成第二小節(jié)的說明。完成了多module之間通過aidl進行pojo類型的數(shù)據(jù)的單向傳遞 [service --> client]

但是,最后一個問題還沒有解決,就是雙向的傳遞 [service client]

好了,那我們就去實現(xiàn)一下吧。

首先,在RemoteBinder中新添加一個方法void setDuck(Duck d);。添加之后,差不多長這樣的:

// RemoteBinder.aidl

package com.pythoncat.aidl;

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

import com.pythoncat.aidl.bean.Duck;

interface RemoteBinder {

/**

* 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);

int getResult();

void setResult(in int result);

Duck getDuck();

void setDuck(in Duck duck); // in is ok

}

至于上面為什么要加上in,這個涉及到aidl中定向tag相關的知識點,這里我不多介紹了。

再次rebuild項目。結(jié)束之后,發(fā)現(xiàn)又報錯了,說你的MyBinder不是抽象類,而且有沒有實現(xiàn)的抽象方法void setDuck(Duck d)。于是,就實現(xiàn)一下。那么,現(xiàn)在。MyBinder長這樣子:

public class MyBinder extends RemoteBinder.Stub {

private Duck duck;

private int result;

@Override

public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

}

@Override

public int getResult() throws RemoteException {

if (result == 0) {

return new Random().nextInt(500);

} else {

return this.result;

}

}

@Override

public void setResult(int result) throws RemoteException {

this.result = result;

}

@Override

public Duck getDuck() throws RemoteException {

if (this.duck == null) {

Duck d = new Duck();

d.id = 10086;

d.name = "DuckTang";

return d;

} else {

this.duck.name = this.duck.name + "&Jerry";

return this.duck;

}

}

@Override

public void setDuck(Duck duck) throws RemoteException {

this.duck = duck;

}

}

ok,服務這邊算是結(jié)束了。接下來,去看調(diào)用者AidlActivity是如何去傳遞一個pojo對象給服務。看起來應該是這樣子的:

if (mRemoteBinder != null) {

try {

mRemoteBinder.setResult(1024);

int result = mRemoteBinder.getResult();

tvShowResult.setText(getString(R.string.show_about_normal_service, result));

LogUtils.e("aidl result===" + result);

Duck duck = new Duck();

duck.name = "pythonCat";

duck.id = 12306;

mRemoteBinder.setDuck(duck);

Duck d = mRemoteBinder.getDuck();

tvParcelable.setText(getString(R.string.show_about_parcelable_service, d.toString()));

LogUtils.e("aidl parcelable===" + d.toString());

} catch (RemoteException e) {

LogUtils.e("bind remote service fail...");

LogUtils.e(e);

}

}

好了,現(xiàn)在一切結(jié)束了。跑起來吧。... 果然,和我們預想的一樣,現(xiàn)在界面顯示的我們傳遞過去的Duck對象。而不是,先前在服務中定義的Duck對象了。

那么,毫無疑問,我們完成了之前的問題。多module之間如何通過aidl實現(xiàn)數(shù)據(jù)的雙向傳遞。

哈哈哈哈哈,我們完成了。

然后呢?

多App之間如何進行aidl?未完待續(xù)吧,或者沒有下文了。

總結(jié)

以上是生活随笔為你收集整理的Android绑定多个aidl,android aidl 多`module`版的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。