国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[Android AIDL] --- AIDL原理簡(jiǎn)析

這篇具有很好參考價(jià)值的文章主要介紹了[Android AIDL] --- AIDL原理簡(jiǎn)析。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

上一篇文章已經(jīng)講述了如何在Android studio中搭建基于aidl的cs模型框架,只是用起來(lái)了,這次對(duì)aidl及cs端如何調(diào)用的原理進(jìn)行簡(jiǎn)單分析

1 創(chuàng)建AIDL文件

AIDL 文件可以分為兩類。
一類是用來(lái)定義接口方法,聲明要暴露哪些接口給客戶端調(diào)用;
一類用來(lái)聲明實(shí)現(xiàn)了 Parcelable 接口的數(shù)據(jù)類型,以供其他 AIDL 文件使用那些非默認(rèn)支持的數(shù)據(jù)類型。
在 AIDL 文件中需要明確標(biāo)明引用到的數(shù)據(jù)類型所在的包名,即使兩個(gè)文件處在同個(gè)包名下。
默認(rèn)情況下,AIDL 支持下列數(shù)據(jù)類型:

八種基本數(shù)據(jù)類型:byte、char、short、intlong、floatdouble、boolean
String,CharSequence
List類型。List承載的數(shù)據(jù)必須是AIDL支持的類型,或者是其它聲明的AIDL對(duì)象
Map類型。Map承載的數(shù)據(jù)必須是AIDL支持的類型,或者是其它聲明的AIDL對(duì)象

客戶端和服務(wù)端都需要?jiǎng)?chuàng)建,我們先在server端中創(chuàng)建,然后復(fù)制到client端即可。在 Android Studio 中右鍵點(diǎn)擊新建一個(gè) AIDL 文件,如圖所示:
[Android AIDL] --- AIDL原理簡(jiǎn)析,Android,android
創(chuàng)建完成后,系統(tǒng)就會(huì)默認(rèn)創(chuàng)建一個(gè) aidl 文件夾,文件夾下的目錄結(jié)構(gòu)即是工程的包名,AIDL 文件就在其中。如圖所示:
[Android AIDL] --- AIDL原理簡(jiǎn)析,Android,android
文件中會(huì)有一個(gè)默認(rèn)方法,可以刪除掉,也可以新增其他方法。

2 實(shí)現(xiàn)接口

創(chuàng)建或修改過(guò) AIDL 文件后需要 build 下工程,Android SDK 工具會(huì)生成以 .aidl 文件命名的 .java 接口文件(例如,IRemoteService.aidl 生成的文件名是 IRemoteService.java),在進(jìn)程間通信中真正起作用的就是該文件。生成的接口包含一個(gè)名為 Stub 的子類(例如,IRemoteService.Stub),該子類是其父接口的抽象實(shí)現(xiàn),并且會(huì)聲明 AIDL 文件中的所有方法。
如要實(shí)現(xiàn) AIDL 生成的接口,請(qǐng)實(shí)例化生成的 Binder 子類(例如,IRemoteService.Stub),并實(shí)現(xiàn)繼承自 AIDL 文件的方法。
以下是使用匿名內(nèi)部類實(shí)現(xiàn) IRemoteService 接口的示例:

private final IRemoteService.Stub binder = new IRemoteService.Stub() {
    public int getPid(){
        return Process.myPid();
    }
    public void basicTypes(int anInt, long aLong, boolean aBoolean,
        float aFloat, double aDouble, String aString) {
        // Does nothing
    }
};

現(xiàn)在,binder 是 Stub 類的一個(gè)實(shí)例(一個(gè) Binder),其定義了服務(wù)端的 RPC 接口。

3 server端公開(kāi)接口

在為服務(wù)端實(shí)現(xiàn)接口后,需要向客戶端公開(kāi)該接口,以便客戶端進(jìn)行綁定。創(chuàng)建 Service 并實(shí)現(xiàn) onBind(),從而返回生成的 Stub 的類實(shí)例。以下是服務(wù)端的示例代碼:

public class RemoteService extends Service {
    private final String TAG = "RemoteService";

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // Return the interface
        Log.d(TAG, "onBind");
        return binder;
    }

    private final IRemoteService.Stub binder = new IRemoteService.Stub() {
        public int getPid() {
            return Process.myPid();
        }

        public void basicTypes(int anInt, long aLong, boolean aBoolean,
                               float aFloat, double aDouble, String aString) {
            Log.d(TAG, "basicTypes anInt:" + anInt + ";aLong:" + aLong + ";aBoolean:" + aBoolean + ";aFloat:" + aFloat + ";aDouble:" + aDouble + ";aString:" + aString);
        }
    };
}

我們還需要在 Manefest 文件中注冊(cè)我們創(chuàng)建的這個(gè) Service,否則客戶端無(wú)法綁定服務(wù)。

      <service
            android:name=".RemoteService"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="com.example.aidl"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </service>

4 client 端調(diào)用IPC方法

當(dāng)客戶端(如 Activity)調(diào)用 bindService() 以連接此服務(wù)時(shí),客戶端的 onServiceConnected() 回調(diào)會(huì)接收服務(wù)端的 onBind() 方法所返回的 binder 實(shí)例。
客戶端還必須擁有接口類的訪問(wèn)權(quán)限,因此如果客戶端和服務(wù)端在不同應(yīng)用內(nèi),則客戶端應(yīng)用的 src/ 目錄內(nèi)必須包含 .aidl 文件(該文件會(huì)生成 android.os.Binder 接口,進(jìn)而為客戶端提供 AIDL 方法的訪問(wèn)權(quán)限)的副本。所以我們需要把服務(wù)端的 aidl 文件夾整個(gè)復(fù)制到客戶端的 java 文件夾同個(gè)層級(jí)下,不需要改動(dòng)任何代碼。
當(dāng)客戶端在 onServiceConnected() 回調(diào)中收到 IBinder 時(shí),它必須調(diào)用 IRemoteService.Stub.asInterface(service),以將返回的參數(shù)轉(zhuǎn)換成 IRemoteService 類型。例如:

IRemoteService iRemoteService;
private ServiceConnection mConnection = new ServiceConnection() {
    // Called when the connection with the service is established
    public void onServiceConnected(ComponentName className, IBinder service) {
        // Following the example above for an AIDL interface,
        // this gets an instance of the IRemoteInterface, which we can use to call on the service
        iRemoteService = IRemoteService.Stub.asInterface(service);
    }

    // Called when the connection with the service disconnects unexpectedly
    public void onServiceDisconnected(ComponentName className) {
        Log.e(TAG, "Service has unexpectedly disconnected");
        iRemoteService = null;
    }
};

獲得了 iRemoteService 對(duì)象,我們就可以調(diào)用 AIDL 中定義的方法了。如要斷開(kāi)連接,可以調(diào)用unbindService() 方法。以下是客戶端的示例代碼:

public class MainActivity extends AppCompatActivity {
    private final String TAG = "ClientActivity";
    private IRemoteService iRemoteService;
    private Button mBindServiceButton;

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

        mBindServiceButton = findViewById(R.id.btn_bind_service);
        mBindServiceButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = mBindServiceButton.getText().toString();
                if ("Bind Service".equals(text)) {
                    Intent intent = new Intent();
                    intent.setAction("com.example.aidl");
                    intent.setPackage("com.example.aidl.server");
                    bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
                } else {
                    unbindService(mConnection);
                    mBindServiceButton.setText("Bind Service");
                }
            }
        });
    }

    ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.d(TAG, "onServiceDisconnected");
            iRemoteService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.d(TAG, "onServiceConnected");
            iRemoteService = IRemoteService.Stub.asInterface(service);
            try {
                int pid = iRemoteService.getPid();
                int currentPid = Process.myPid();
                Log.d(TAG, "currentPID: " + currentPid + ", remotePID: " + pid);
                iRemoteService.basicTypes(12, 123, true, 123.4f, 123.45,
                        "服務(wù)端你好,我是客戶端");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            mBindServiceButton.setText("Unbind Service");
        }
    };
}

5 通過(guò)IPC傳遞對(duì)象

除了上面默認(rèn)支持的數(shù)據(jù)類型,AIDL 還可以傳遞對(duì)象,但是該類必須實(shí)現(xiàn) Parcelable 接口。而該類是兩個(gè)應(yīng)用間都需要使用到的,所以也需要在 AIDL 文件中聲明該類,為了避免出現(xiàn)類名重復(fù)導(dǎo)致無(wú)法創(chuàng)建 AIDL 文件的錯(cuò)誤,這里需要先創(chuàng)建 AIDL 文件,之后再創(chuàng)建類。
先在服務(wù)端新建一個(gè) AIDL 文件,比如 Rect.aidl,示例如下:

// Rect.aidl
package com.example.aidl.server;

// Declare Rect so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable Rect;

然后就可以創(chuàng)建 Rect 類了,并使之實(shí)現(xiàn) Parcelable 接口。示例代碼如下:

public class Rect implements Parcelable {
    private int left;
    private int top;
    private int right;
    private int bottom;

    public Rect(int left, int top, int right, int bottom) {
        this.left = left;
        this.top = top;
        this.right = right;
        this.bottom = bottom;
    }

    public static final Parcelable.Creator<Rect> CREATOR = new Parcelable.Creator<Rect>() {
        public Rect createFromParcel(Parcel in) {
            return new Rect(in);
        }

        public Rect[] newArray(int size) {
            return new Rect[size];
        }
    };

    private Rect(Parcel in) {
        readFromParcel(in);
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(left);
        out.writeInt(top);
        out.writeInt(right);
        out.writeInt(bottom);
    }

    public void readFromParcel(Parcel in) {
        left = in.readInt();
        top = in.readInt();
        right = in.readInt();
        bottom = in.readInt();
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @NonNull
    @Override
    public String toString() {
        return "Rect[left:" + left + ",top:" + top + ",right:" + right + ",bottom:" + bottom + "]";
    }
}

這樣我們就可以在之前創(chuàng)建的 IRemoteService.aidl 中新增一個(gè)方法來(lái)傳遞 Rect 對(duì)象了,示例代碼如下:

// IRemoteService.aidl
package com.example.aidl.server;
import com.example.aidl.server.Rect;

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

interface IRemoteService {
    /**
     * 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 getPid();

    void addRectInOut(inout Rect rect);
}

注意這里需要明確導(dǎo)包:

import com.example.aidl.server.Rect;

然后將新增的 Rect.aidl 文件和 Rect.java 文件還有修改的 IRemoteService.aidl 文件同步到客戶端相同路徑下,如圖所示:
[Android AIDL] --- AIDL原理簡(jiǎn)析,Android,android
build 下工程,就可以在客戶端調(diào)用到該 addRectInOut 方法了。示例代碼如下:文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-683619.html

    ServiceConnection mConnection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iRemoteService = IRemoteService.Stub.asInterface(service);
            try {
                iRemoteService.addRectInOut(new Rect(1, 2, 3, 4));
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };

到了這里,關(guān)于[Android AIDL] --- AIDL原理簡(jiǎn)析的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Android studio 無(wú)法創(chuàng)建AIDL文件

    Android studio 無(wú)法創(chuàng)建AIDL文件

    Android studio 創(chuàng)建AIDL文件的時(shí)候 提示是灰色的無(wú)法創(chuàng)建 處理方法在app下面的build.gradle中的buildFeatures 添加 aidl = true 這個(gè)是 kotlin的寫法,如果是使用的舊項(xiàng)目修改下格式就行

    2024年01月25日
    瀏覽(19)
  • android aidl進(jìn)程間通信封裝通用實(shí)現(xiàn)

    接上一篇的分析,今天繼續(xù) aidl復(fù)雜流程封裝-CSDN博客 今天的任務(wù)就是將代碼梳理下放進(jìn)來(lái) 1 項(xiàng)目gradle配置: ? ?需要將對(duì)應(yīng)的代碼放到各自的目錄下,這里僅貼下關(guān)鍵內(nèi)容,細(xì)節(jié)可以下載代碼慢慢看 ? ? sourceSets { ? ? ? ? main { ? ? ? ? ? ? manifest.srcFile \\\'src/main/AndroidManife

    2024年02月22日
    瀏覽(20)
  • Android 使用AIDL傳輸超大型文件

    Android 使用AIDL傳輸超大型文件

    最近在寫車載Android的第5篇視頻教程「AIDL的實(shí)踐與封裝」時(shí),遇到一個(gè)有意思的問(wèn)題,能不能通過(guò)AIDL傳輸超過(guò) 1M 以上的文件? 我們先不細(xì)究,為什么要用AIDL傳遞大文件,單純從技術(shù)的角度考慮能不能實(shí)現(xiàn)。眾所周知,AIDL是一種基于Binder實(shí)現(xiàn)的跨進(jìn)程調(diào)用方案,Binder 對(duì)傳輸

    2024年02月10日
    瀏覽(21)
  • Android Binder——APP中AIDL實(shí)現(xiàn)(十九)

    ????????AIDL(Android Interface Definition Language)其實(shí)就是對(duì) Binder 通信的一個(gè)封裝,方便在開(kāi)發(fā)中對(duì) Binder 通信的使用,這里我們就從頭開(kāi)始來(lái)看一下 AIDL 通信的創(chuàng)建過(guò)程。 ????????通過(guò) Android Studio 的 File -New - AIDL 的方式就會(huì)生成對(duì)應(yīng)包名的 aidl 文件。即 aidl 文件要與應(yīng)用

    2024年04月28日
    瀏覽(36)
  • 深入解析Android AIDL:實(shí)現(xiàn)跨進(jìn)程通信的利器

    深入解析Android AIDL:實(shí)現(xiàn)跨進(jìn)程通信的利器

    Android Interface Definition Language (AIDL) 是一種Android系統(tǒng)中的跨進(jìn)程通信機(jī)制。AIDL允許一個(gè)應(yīng)用程序的組件與另一個(gè)應(yīng)用程序的組件通信,并在兩者之間傳輸數(shù)據(jù)。 AIDL的主要作用是幫助不同進(jìn)程間共享數(shù)據(jù)和服務(wù),讓他們能夠互相調(diào)用。例如,在開(kāi)發(fā)一個(gè)多功能的音樂(lè)播放器時(shí),

    2024年02月19日
    瀏覽(24)
  • Android中AIDL的簡(jiǎn)單使用(Hello world)

    Android中AIDL的簡(jiǎn)單使用(Hello world)

    AIDL:Android Interface Definition Language(Android接口定義語(yǔ)言) 作用:跨進(jìn)程通訊。如A應(yīng)用調(diào)用B應(yīng)用提供的接口 A應(yīng)用創(chuàng)建aidl接口,并且創(chuàng)建一個(gè)Service來(lái)實(shí)現(xiàn)這個(gè)接口(在onBind方法里面return我們這個(gè)接口的實(shí)例)。 把A應(yīng)用創(chuàng)建的aidl文件原封不動(dòng)的搬至B應(yīng)用中(注意包名類名都

    2024年02月11日
    瀏覽(24)
  • android aidl進(jìn)程間通信封裝通用實(shí)現(xiàn)-用法說(shuō)明

    接上一篇:android aidl進(jìn)程間通信封裝通用實(shí)現(xiàn)-CSDN博客 該aar包的使用還是比較方便的 一先看客戶端 1 初始化 2 發(fā)送事件: ?就是通過(guò)json的形式將參數(shù)包裹進(jìn)來(lái),另一端統(tǒng)一解析 ?唯一標(biāo)志位:KEY_CLIENT_REQUEST_AUTHOR 是必須要加的,不然區(qū)分不出來(lái)是那個(gè)客戶端 二再看服務(wù)端

    2024年02月20日
    瀏覽(21)
  • Android:AIDL簡(jiǎn)單介紹+傳遞簡(jiǎn)單數(shù)據(jù)+傳遞復(fù)雜數(shù)據(jù)

    Android:AIDL簡(jiǎn)單介紹+傳遞簡(jiǎn)單數(shù)據(jù)+傳遞復(fù)雜數(shù)據(jù)

    對(duì)于AIDL的學(xué)習(xí),這些也只能說(shuō)是我在學(xué)習(xí)中的理解,有理解不到位或者錯(cuò)的地方也歡迎指正。 AIDL的目的就是實(shí)現(xiàn)進(jìn)程之間的通信, 尤其是在涉及多進(jìn)程并發(fā)情況下的進(jìn)程間通信 ??梢詫idl理解為兩個(gè)進(jìn)程之間的橋梁,并制定規(guī)則,使其傳輸特定數(shù)據(jù)。 1.AIDL支持的數(shù)據(jù)類型

    2024年02月21日
    瀏覽(19)
  • Android FFmpeg應(yīng)用簡(jiǎn)析

    FFmpeg是一個(gè)跨平臺(tái)的自由軟件,可用于錄制、轉(zhuǎn)換和流式傳輸音頻和視頻。它包含了非常多的音頻/視頻編解碼庫(kù)、封裝格式庫(kù)以及工具庫(kù)。它不僅支持各種常用的音視頻格式,而且支持一些非常罕見(jiàn)的格式。 FFmpeg實(shí)際上是一個(gè)命令行工具,可以在終端窗口中使用。它可以在

    2024年02月13日
    瀏覽(14)
  • Android Binder常用案例使用分析,跨進(jìn)程通信aidl

    Android Binder常用案例使用分析,跨進(jìn)程通信aidl

    service組件的binderService獲取binder通信。 servicemanager.getService方法獲取相關(guān)服務(wù)。 本質(zhì)上都是IBinder通信。 客戶端:使用intent,啟動(dòng)服務(wù)端的service,使用binderservice,在onServiceConnected回調(diào)方法中獲取服務(wù)端的實(shí)際binder對(duì)象。使用aidl中的接口調(diào)用服務(wù)端的方法即可。 服務(wù)端:定義

    2024年02月07日
    瀏覽(30)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包