bindServiceメソッドを介してサーバーのプロキシオブジェクトを取得し、aidlファイルで定義されたメソッドを呼び出します。重要なプロセスはバインダーオブジェクトの転送であり、サーバーのバインダーオブジェクトはAMSを介してクライアントに渡されます。
サーバ側
MathService.aidl
パッケージcom.sunday.aidl;
IMathServiceインターフェース
{{
long add(long a、long b);
}
IMathService.javaファイルはgenディレクトリに自動的に生成されます
MathService .java
パッケージcom.sunday.aidl;
android.app.Serviceをインポートします。
android.content.Intentをインポートします。
android.os.IBinderをインポートします。
パブリック クラスMathServiceはサービスを拡張します
{{
パブリック クラスMathServiceImplはIMathService.Stubを拡張します
{{
@オーバーライド
public long add(long a、long b)
{{
a + bを返します。
}
}
@オーバーライド
public IBinder onBind(Intent intent)
{{
新しいMathServiceImpl();を返します。
}
}
AndroidManifest.xmlにサービスレコードを追加します
クライアント側
MainActivity .java
パブリック クラスMainActivityはActionBarActivityを拡張し、 OnClickListener {を実装します
プライベートMyConnectionとserviceConnection =新しいMyConnectionと();
プライベートIMathService myServiceという= nullを。
パブリック クラスmyConnectionはServiceConnectionを実装します
{{
@オーバーライド
public void onServiceConnected(ComponentName name、IBinder service)
{{
myService = IMathService.Stub。asInterface(サービス);
}
@オーバーライド
public void onServiceDisconnected(ComponentName name)
{{
}
}
@オーバーライド
public void onClick(ビュービュー)
{{
{を 試してください
long ret = myService .add(2017、1);
トースト。makeText(this、
「結果は」+ ret、トーストです。LENGTH_LONG).show();
} catch(例外e){
// TODO:例外を処理します
}
}
@オーバーライド
protected void onCreate(Bundle savedInstanceState){
super .onCreate(savedInstanceState);
setContentView(R.layout。activity_main);
bindService(new Intent("com.sunday.aidl.IMathService" )、
serviceConnection 、BIND_AUTO_CREATE);
ボタンaButton =(ボタン)findViewById(R.id。ボタン1);
aButton.setOnClickListener(this);
}
プロセスを表示
1 |不明:/#ps | grep aidl
u0_a103 28072 608 1771868 71060 SyS_epoll_ 792c011794 S com.example.aidlclient
u0_a102 28108 608 1715168 46232 SyS_epoll_ 792c011794 S com.sunday.aidl
各ステップはバインダー通信呼び出しです
奉献理論
bindServiceの処理を研究し、開始理論を検証します
サーバーはユーザーサービスのIBinderオブジェクトを取得し、それをクライアントに返して使用します。クライアントはそれを使用できます。これがIBinderオブジェクトの配信です。
myServer.cpp
#include <stdio.h>
#include <binder / IInterface.h>
#include <binder / Parcel.h>
#include <binder / IBinder.h>
#include <binder / Binder.h>
#include <binder / ProcessState.h>
#include <binder / IPCThreadState.h>
#include <binder / IServiceManager.h>
名前空間androidを使用します。
//
sp <IBinder> aBinder = NULL;
クラスmyBinder:パブリックBBinder
{{
公衆:
status_t dump(int fd、const Vector <String16>&args)
{{
write(fd、 "myBinderダンプが呼び出されました"、22);
NO_ERRORを返します。
}
status_t onTransact(
uint32_tコード、const Parcel&データ、Parcel *応答、uint32_t / *フラグ* /)
{{
スイッチ(コード){
ケースDUMP_TRANSACTION:{
printf( "ダンプが呼び出されました\ n");
int fd = data.readFileDescriptor();
int argc = data.readInt32();
Vector <String16> args;
for(int i = 0; i <argc && data.dataAvail()> 0; i ++){
args.add(data.readString16());
}
dump(fd、args);を返します。
}
ケース2:{
int num = data.readInt32();
printf( "onTransactが呼び出されました、ケース2、num =%d \ n"、num);
返信-> writeInt32(num * 2);
NO_ERRORを返します。
}
ケース3:{
printf( "onTransactが呼び出されました、ケース3 \ n");
返信-> writeStrongBinder(aBinder);
NO_ERRORを返します。
}
}
NO_ERRORを返します。
}
};
int main()
{{
sp <ProcessState> proc(ProcessState :: self());
sp <IServiceManager> sm = defaultServiceManager();
//サービスを受ける
sp <IBinder> service = sm-> checkService(String16( "user"));
if(service!= NULL){
printf( "サービスを受ける\ n");
そこから=サービス;
}
sm-> addService(String16( "myService")、new myBinder());
printf( "add myService \ n");
ProcessState :: self()-> startThreadPool();
IPCThreadState :: self()-> joinThreadPool();
0を返します。
}
myClient.cpp
#include <binder / Parcel.h>
#include <binder / ProcessState.h>
#include <binder / IServiceManager.h>
#include <binder / TextOutput.h>
#include <utils / Vector.h>
#include <binder / BpBinder.h> //
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
名前空間androidを使用します。
int main(int argc、char * const argv [])
{{
sp <IServiceManager> sm = defaultServiceManager();
fflush(stdout);
if(sm == NULL)
{{
ALOGE( "デフォルトのサービスマネージャーを取得できません!");
aerr << "dumpsys:デフォルトのサービスマネージャーを取得できません!" << endl;
20を返します。
}
Vector <String16> args;
sp <IBinder> service = sm-> checkService(String16( "myService"));
int err = service-> dump(STDOUT_FILENO、args);
if(err!= 0){
aerr << "エラーダンプサービス情報:(" << strerror(err)
<< ")" << endl;
}
if(argc <= 1)
{{
// printf( "argc <= 1 \ n");
1を返します。
}
int num = atoi(argv [1]);
printf( "num =%d \ n"、num);
区画データ;
小包の返信;
data.writeInt32(num);
err = service-> transaction(3、data、&reply、0);
if(err == NO_ERROR)
{{
// reply.setDataPosition(0);
printf( "\ n返信を受け取る\ n");
sp <IBinder> sBinder = reply.readStrongBinder();
//ユーザーサービスのdumpメソッドが呼び出されます
sBinder-> dump(STDOUT_FILENO、args);
}
0を返します。
}
Android.mk
LOCAL_PATH:= $(my-dirを呼び出す)
$(CLEAR_VARS)を含める
LOCAL_SRC_FILES:= \
myServer.cpp
LOCAL_SHARED_LIBRARIES:= \
libbase \
libutils \
liblog \
libbinder
ifeq($(TARGET_OS)、linux)
LOCAL_CFLAGS + = -DXP_UNIX
#LOCAL_SHARED_LIBRARIES + = librt
endif
LOCAL_MODULE:= bServer
$(BUILD_EXECUTABLE)を含める
$(CLEAR_VARS)を含める
LOCAL_SRC_FILES:= \
myClient.cpp
LOCAL_SHARED_LIBRARIES:= \
libbase \
libutils \
liblog \
libbinder
ifeq($(TARGET_OS)、linux)
LOCAL_CFLAGS + = -DXP_UNIX
#LOCAL_SHARED_LIBRARIES + = librt
endif
LOCAL_MODULE:= bClient
$(BUILD_EXECUTABLE)を含める
テスト
不明:/ data / local / tmp#。/ bServer
サービスを受ける
myServiceを追加します
と呼ばれるダンプ
onTransactが呼び出され、ケース3
不明:/ data / local / tmp#。/ bClient 0
num = 0と呼ばれるmyBinderダンプ
返信を得る
ユーザー:
UserInfo {0:null:13} serialNo = 0
作成:<不明>
最終ログイン:+ 13d1h6m53s828ms前
ユーザーサービスのダンプメソッドが実行されます