您的位置:首页 > 大数据 > 人工智能

AIDL的一点理解

2013-07-11 13:42 246 查看


AIDL的一点理解

分类: Android2013-07-10
22:19 68人阅读 评论(0) 收藏 举报

AIDL
两个APK通信

最近参与了一个项目,其中有用到两个APK间进行通信,最终采用的是AIDL,于是自己小研究了下,如有错误,请大家指正。

1. 创建.aidl文件

首先,创建.aidl文件。这个文件类似于声明文件,对于服务器端而言,就是声明你需要对外提供什么接口;对于客户端来说,声明了自己将要用到的接口。所以,不仅服务器端要创建.aidl文件,客户端同样需要。而且是客户端的.aidl文件要和服务器端的一样。所以服务器端一旦公布了对外接口,最好就不要改啦,因为会有很多客户端将用。

下面这两个文件IEmilyService.aidl 是EmilyService.apk 里的定义的,IEmilyServiceCallBack.aidl 这个是EmilySecondClient.apk定义的,因为这个两个apk需要进行双向通信。

但是在两个apk中,这个两个文件是必须都具备的。说白了就是为了方便互相调接口...

IEmilyService.aidl

[java] view
plaincopyprint?

package com.example.fwk;

import com.example.fwk.IEmilyServiceCallBack;

interface IEmilyService {

void registerCallback(IEmilyServiceCallBack cb);

void unregisterCallback(IEmilyServiceCallBack cb);

void serviceShow();

}

IEmilyServiceCallBack.aidl

[java] view
plaincopyprint?

package com.example.fwk;

interface IEmilyServiceCallBack {

void serviceCallBackShow();

}

2. 实现接口并将接口暴露给客户端

这个两个文件在编译后会自动生成.java文件。额,因为我用的是eclipse, 一运行就自己生成了,也没仔细看里面具体都有啥。从文档里得知,里面东西还是很重要的。尤其是一个内部类Stub,它是父类接口的抽象实现,里面定义了.aidl中的所有方法。

mBinder是IEmilyService.Stub的对象,里面实现了IEmilyService.aidl里定义的所有方法。当有客户端连接的时候,也就是来onBind(), 客户端会得到mBinder这个实例。

EmilyService

[java] view
plaincopyprint?

package com.example.emilyservice;

import com.example.fwk.IEmilyService;

import com.example.fwk.IEmilyServiceCallBack;

import android.os.IBinder;

import android.os.RemoteCallbackList;

import android.os.RemoteException;

import android.app.Service;

import android.content.Intent;

import android.util.Log;

public class EmilyService extends Service {

private static final String TAG = "EmilyService";

/*

* This is a list of callbacks that have been registered with the

* service.

*/

final RemoteCallbackList<IEmilyServiceCallBack> mCallbacks =

new RemoteCallbackList<IEmilyServiceCallBack>();

/*

* Implements the interface.

* 1. The mBinder is an instance of the Stub class (a Binder), which defines the RPC interface for the service.

* 2. This instance will be exposed to clients, so the clients can interact with the service.

* 3. If one service takes too much time to complete a request, you should avoid to call it from the main thread,

* you should call it from a separate thread in the client, in this way to avoid ANR.

*/

private final IEmilyService.Stub mBinder = new IEmilyService.Stub() {

public void registerCallback(IEmilyServiceCallBack cb) {

Log.i(TAG, "___________registerCallback()");

if (cb != null) mCallbacks.register(cb);

}

public void unregisterCallback(IEmilyServiceCallBack cb) {

Log.i(TAG, "___________unregisterCallback()");

if (cb != null) mCallbacks.unregister(cb);

}

public void serviceShow() throws RemoteException {

Log.i(TAG, "___________serviceShow()");

testClients(null);

}

};

@Override

public IBinder onBind(Intent intent) {

// TODO Auto-generated method stub

return mBinder;

}

/*

* Test the clients.

*/

public void testClients(IEmilyServiceCallBack cb) {

if (cb != null) {

Log.i(TAG, "cb != null");

try {

cb.serviceCallBackShow();

} catch (RemoteException e) {

}

} else {

// Broadcast to all clients the new value.

final int count = mCallbacks.beginBroadcast();

for (int i=0; i < count; i++) {

try {

Log.i(TAG, "onServiceShowFinished____i = " + i);

mCallbacks.getBroadcastItem(i).serviceCallBackShow();

} catch (RemoteException e) {

}

}

mCallbacks.finishBroadcast();

}

}

}

3. 当一个客户端调bindservice()去连接service的时候,客户端调用onServiceConected()回调方法。

Client

[java] view
plaincopyprint?

package com.example.emilysecondclient;

import com.example.fwk.IEmilyService;

import com.example.fwk.IEmilyServiceCallBack;

import android.os.Bundle;

import android.os.IBinder;

import android.os.RemoteException;

import android.app.Activity;

import android.content.ComponentName;

import android.content.Context;

import android.content.Intent;

import android.content.ServiceConnection;

import android.util.Log;

import android.view.Menu;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

public class MainActivity extends Activity {

private static String TAG = "EmilySecondClient";

private static String ACTION_START_EMILY_SERVICE = "android.intent.action.EMILY_SERVICE";

private IEmilyService mEmilyService = null;

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

// When the client call the bindService() to connect to Emily service,

// the client's onServiceConnected() callback receives IBinder that the

// client can use to communicate with the service.

Intent serviceIntent = new Intent(ACTION_START_EMILY_SERVICE);

bindService(serviceIntent, mEmilyServiceConnection, Context.BIND_AUTO_CREATE);

Button button1 = (Button)findViewById(R.id.button1);

button1.setOnClickListener(new OnClickListener() {

public void onClick(View v) {

serviceShowInClient();

}

});

}

@Override

public boolean onCreateOptionsMenu(Menu menu) {

getMenuInflater().inflate(R.menu.activity_main, menu);

return true;

}

private final ServiceConnection mEmilyServiceConnection = new ServiceConnection() {

// Called when the connection with the service is established.

public void onServiceConnected(ComponentName className, IBinder service) {

Log.i(TAG, "call service connected");

mEmilyService = IEmilyService.Stub.asInterface(service);

// We want to monitor the service for as long as we are

// connected to it.

try {

mEmilyService.registerCallback(mCallBack);

} catch (RemoteException e) {

}

}

public void onServiceDisconnected(ComponentName className) {

Log.i(TAG, "call service disconnected");

mEmilyService = null;

}

};

private final IEmilyServiceCallBack.Stub mCallBack = new IEmilyServiceCallBack.Stub() {

public void serviceCallBackShow() throws RemoteException {

Log.i(TAG, "___________serviceCallBackShow()");

}

};

private void serviceShowInClient() {

try {

mEmilyService.serviceShow();

} catch (RemoteException e) {

e.printStackTrace();

}

}

}

以上只贴出来了一个Client的代码,另外一个client代码是类似的。

下面是运行出的log.

The log

[plain] view
plaincopyprint?

I/EmilyFirstClient( 4163): call service connected

I/EmilyService( 4084): Binder API: registerCallback()

I/EmilyService( 4084): ___________serviceShow()

I/EmilySecondClient( 4206): call service connected

I/EmilyService( 4084): Binder API: registerCallback()

I/EmilyService( 4084): ___________serviceShow()

I/EmilyFirstClient( 6830): call service connected

I/EmilyService( 6711): ___________registerCallback()

I/EmilyService( 6711): ___________serviceShow()

I/EmilyService( 6711): onServiceShowFinished____i = 0

I/EmilyFirstClient( 6830): ___________serviceCallBackShow()

I/EmilySecondClient( 6931): call service connected

I/EmilyService( 6711): ___________registerCallback()

I/EmilyService( 6711): ___________serviceShow()

I/EmilyService( 6711): onServiceShowFinished____i = 0

I/EmilySecondClient( 6931): ___________serviceCallBackShow()

还是要好好研究下:

http://developer.android.com/guide/components/aidl.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: