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;
もっと知る必要があります、あなたは前に書かれた援助の紹介記事を書くことができます