AidlAdvanced-カスタムタイプトランスミッション

2020.8.7最初の編集。つづく。。 

2020.8.112番目の編集。つづく。

2020.8.12第3版。つづく。

この記事のディレクトリ構造は次のとおりです。

AidlParcelableDemo
   |--client                                    
   |     |--src
   |     |   |--main
   |     |        |--aidl
   |     |        |    |--com.zhouxi.client
   |     |        |            |--IAidlService.aidl------------------------(1)
   |     |        |            |--ParcelableInfo.aidl----------------------(2)
   |     |        |--java
   |     |        |    |--com.zhouxi.client
   |     |        |            |--MainActivity.java------------------------(3)
   |     |        |            |--ParcelableInfo.java----------------------(4)
   |     
   |--aidlservice
   |     |--src
   |     |   |--main
   |     |        |--aidl
   |     |        |    |--com.zhouxi.client
   |     |        |            |--IAidlService.aidl-----------------------(5)
   |     |        |            |--ParcelableInfo.aidl---------------------(6)
   |     |        |--java
   |     |        |    |--com.zhouxi.client
   |     |        |            |--AidlService.java------------------------(7)
   |     |        |            |--ParcelableInfo.java---------------------(8)

                              AidlParcelableDemo目录结构

前回の記事では、AIDLの基本的な知識を紹介し、サンプルコードを介してAIDLの実行プロセスを示しました。データはAIDLインターフェイス、つまり通信を介して2つのapk間で転送されますが、上記で渡されるデータは主に基本的なデータです。 。実際、AIDLはカスタムデータ型などの他のデータ型の送信もサポートしています。この記事では主にカスタムデータ型の送信に焦点を当てています(AIDLの原理は途中で過度に説明されていません。理解できない場合は、前の記事を読むことができます)最初にクライアントのコードに移動します。

package com.zhouxi.client;

import androidx.appcompat.app.AppCompatActivity;
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;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {
    public static final String TAG = MainActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.bindAidlService).setOnClickListener(this);
        findViewById(R.id.unbindAidlService).setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        if (v.getId() == R.id.bindAidlService) {
            Intent intent = new Intent();
            intent.setAction("com.zhouxi.service.AidlService");
            intent.setPackage("com.zhouxi.service");
            bindService(intent, aidlServiceConnection, Context.BIND_AUTO_CREATE);
        } else if (v.getId() == R.id.unbindAidlService) {
            Log.e(TAG, "onClick: unbindAidlService");
            unbindService(aidlServiceConnection);
        }
    }

    public ServiceConnection aidlServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            ParcelableInfo inParcelableInfo = new ParcelableInfo("这是一条传入的自定义类型");
            Log.e(TAG, "onServiceConnected: bind AidlService success.");
            IAidlService aidlService = IAidlService.Stub.asInterface(service);
            try {
                Log.e(TAG, "onServiceConnected: the info of AidlService: " + aidlService.getServiceInfo(inParcelableInfo).getInfo());
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.e(TAG, "onServiceConnected: bind AidlService fail.");
        }
    };
}

apkは、AidlServiceをバインドおよびバインド解除するための2つのボタンを定義します。バインドが成功すると、AidlServiceは独自のプロキシクラスを返します。 

IAidlService aidlService = IAidlService.Stub.asInterface(service);

 プロキシクラスを取得した後、AIDLインターフェイスを介してAidlServiceのデータにアクセスし(特定の実装はインターフェイスによって異なります)、aidlファイルを確認し、IAIdlServiceがgetServiceInfoメソッドを定義し、ParcelableInfoのカスタムデータ型を渡します。戻り値もこのタイプです。最初にこのデータ型を想像して、基本的なデータ型を理解してください。

// IAidlService.aidl
package com.zhouxi.client;

import com.zhouxi.client.ParcelableInfo;

interface IAidlService {
    ParcelableInfo getServiceInfo(in ParcelableInfo inParcelableInfo);
}

AidlServiceでこのインターフェースの特定の実装を表示する 

package com.zhouxi.client;

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

import androidx.annotation.Nullable;

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

    @Override
    public void onCreate() {
        Log.e(TAG, "onCreate: AidlService is onCreate.");
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand: AidlService is onStartCommand.");
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy: AidlService is onDestroy.");
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Log.e(TAG, "onBind: AidlService is onBind.");
        return new AidlBinder();
    }

    @Override
    public boolean onUnbind(Intent intent) {
        Log.e(TAG, "onUnbind: AidlService is onUnbind.");
        return super.onUnbind(intent);
    }

    class AidlBinder extends IAidlService.Stub {
        @Override
        public ParcelableInfo getServiceInfo(ParcelableInfo inParcelbleInfo) {
            Log.e(TAG, "the inParcelbleInfo is: " + inParcelbleInfo.getInfo());
            inParcelbleInfo.setInfo("这是一条传出的自定义类型");
            return inParcelbleInfo;
        }
    }
}

IAIdlServiceのインターフェースメソッドがAidlServiceに実装され、ParcelbleInfoの入力パラメーターのフィールドが他の情報と出力に変更され、apk全体間の呼び出し関係が終了したことがわかります。次に、 AIDLインターフェースを介して渡されるカスタムタイプ

まず、新しいカスタムタイプのParcelableInfoを作成し、同時にParcelableインターフェイスを実装すると、IDEはParcelableインターフェイスを実装してオーバーライドするように自動的に要求します。

ParcelableInfoに必要なフィールドとメソッドを設定します

上記からわかるように、AIDLインターフェイス転送に使用されるカスタムタイプの生成は非常に簡単です。新しいクラスを作成し、クラス内の関数を実装し、Parcelableインターフェイスを実装します。Alter+ Enterはインターフェイスメソッドを自動的に実装します。

package com.zhouxi.client;

import android.os.Parcel;
import android.os.Parcelable;

public class ParcelableInfo implements Parcelable {
    private String info;

    public ParcelableInfo(String info) {
        this.info = info;
    }

    protected ParcelableInfo(Parcel in) {
        info = in.readString();
    }

    public void setInfo(String info) {
        this.info = info;
    }

    public String getInfo() {
        return info;
    }

    /**
     * 反序列化
     */
    public static final Creator<ParcelableInfo> CREATOR = new Creator<ParcelableInfo>() {
        @Override
        public ParcelableInfo createFromParcel(Parcel in) {
            return new ParcelableInfo(in);
        }
        @Override
        public ParcelableInfo[] newArray(int size) {
            return new ParcelableInfo[size];
        }
    };

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

    /**
     * 序列化过程
     *
     * @param dest
     * @param flags
     */
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(info);
    }
}

カスタムタイプの場合、次のように、対応するaidlファイルも宣言する必要があります。パーセル可能タイプとカスタムタイプ名ParcelableInfoを宣言するだけで済みます。両方のエイドルファイルは、aidlフォルダーの下に配置する必要があります。同時に、クライアントとサービスのパッケージ名が一貫していることを確認してください。

// ParcelableInfo.aidl
package com.zhouxi.client;

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

parcelable ParcelableInfo;

もっと知る必要があります、あなたは前に書かれた援助の紹介記事を書くことができます

 

 

 

おすすめ

転載: blog.csdn.net/weixin_48968045/article/details/107853418