http://developer.android.com/guide/components/aidl.html
aidl(Android Interface Definition Language)是android进程件通信机制。通过AIDL,client和server可以相互调用。
AIDL使用场景:
Using AIDL is necessary only if you allow clients from different applications to access your service for IPC and want to handle multithreading in your service.
If you do not need to perform concurrent IPC across different applications, you should create your interface by implementing a Binder or, if you want to perform IPC, but do not need to handle multithreading, implement your interface using a Messenger. Regardless, be sure that you understand Bound Services before implementing an AIDL.
要掌握的内容:
1,client调用server
2,server回调client
3,参数为复杂类型
下面的代码里展示了1,2
3以后再看吧。。。
AIDL使用步骤:
在这个文件中定义接口方法。
Android SDK tools会根据你的.aidl文件在gen目录下自动生成接口的java文件。这个java接口中有一个内部抽象类叫stub,stub继承自binder并实现了你的AIDL接口中的方法。你必须继承stub并实现那些方法。
3,Expose the interface to clients
实现一个service,重写onBind()方法把自己实现的stub类return。
AIDLServer端代码:
注意要把gen下面自动生成的com.example.aidlserver以及IAIDLCallback.java和IAIDLServer.java拷贝到AIDLCient的src目录下。
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aidlserver"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<service android:name=".AIDLServer" >
<intent-filter>
<action android:name="com.example.aidl" />
</intent-filter>
</service>
</application>
</manifest>
IAIDLServer.aidl
package com.example.aidlserver;
import com.example.aidlserver.IAIDLCallback;
interface IAIDLServer{
//定义client调server的方法
String getValue();
//注册,解注册回调方法
void registerCallback(IAIDLCallback mIAIDLCallback);
void unregisterCallback(IAIDLCallback mIAIDLCallback);
}
IAIDLCallback.aidl
package com.example.aidlserver;
//定义server回调client的方法
interface IAIDLCallback{
void helloWordl();
}
AIDLServer.java
package com.example.aidlserver;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
public class AIDLServer extends Service {
private String TAG = "AIDL";
private boolean debug = true;
private void print(String str) {
if (debug) {
Log.d(TAG, str);
}
}
private final RemoteCallbackList <IAIDLCallback>mCallbacks = new RemoteCallbackList <IAIDLCallback>();
public class AIDLServerImpl extends IAIDLServer.Stub {
@Override
public String getValue() throws RemoteException {
print("getValue()~");
return "灭哈哈哈哈哈~";
}
@Override
public void registerCallback(IAIDLCallback mIAIDLCallback)
throws RemoteException {
print("registerCallback()~");
if (null != mIAIDLCallback) {
mCallbacks.register(mIAIDLCallback);
callback();
}
}
@Override
public void unregisterCallback(IAIDLCallback mIAIDLCallback)
throws RemoteException {
print("unregisterCallback()~");
if (null != mIAIDLCallback) {
mCallbacks.unregister(mIAIDLCallback);
}
}
}
private void callback() {
print("callback()~~~");
final int N = mCallbacks.beginBroadcast();
for (int i=0; i<N; i++) {
try {
//回调client中的方法
mCallbacks.getBroadcastItem(i).helloWordl();
}
catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mCallbacks.finishBroadcast();
}
@Override
public IBinder onBind(Intent intent) {
print("onBind()~");
return new AIDLServerImpl();
}
@Override
public boolean onUnbind(Intent intent) {
print("onUnbind()~");
return super.onUnbind(intent);
}
}
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.aidlclient"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".AIDLClient"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/btn_startAIDLServer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="startAIDLServer" />
<Button
android:id="@+id/btn_stopAIDLServer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="stopAIDLServer" />
<Button
android:id="@+id/btn_invokeAIDLServer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="invokeAIDLServer" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="value is null" />
</LinearLayout>
AIDLClient.java
package com.example.aidlclient;
import android.app.Activity;
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;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.example.aidlserver.*;
public class AIDLClient extends Activity implements OnClickListener {
private Button btnStartAIDLServer;
private Button btnStopAIDLServer;
private Button btnInvokeAIDLServer;
private TextView textView;
private IAIDLServer mServer;
private boolean bind_flag = false;
private String TAG = "AIDL";
private boolean debug = true;
private void print(String str) {
if (debug) {
Log.d(TAG, str);
}
}
private IAIDLCallback mIAIDLCallback = new IAIDLCallback.Stub() {
@Override
public void helloWordl() throws RemoteException {
Log.i(TAG, "hello world!!!!");
}
};
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// 获得服务对象
print("onServiceConnected()");
mServer = IAIDLServer.Stub.asInterface(service);
try {
mServer.registerCallback(mIAIDLCallback);
} catch (RemoteException e) {
}
btnStartAIDLServer.setEnabled(false);
btnStopAIDLServer.setEnabled(true);
btnInvokeAIDLServer.setEnabled(true);
}
@Override
public void onServiceDisconnected(ComponentName name) {
// server连接意外断掉时,收到该消息
print("onServiceDisconnected()");
mServer = null;
btnStartAIDLServer.setEnabled(true);
btnStopAIDLServer.setEnabled(false);
btnInvokeAIDLServer.setEnabled(false);
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnStartAIDLServer = (Button) findViewById(R.id.btn_startAIDLServer);
btnStopAIDLServer = (Button) findViewById(R.id.btn_stopAIDLServer);
btnInvokeAIDLServer = (Button) findViewById(R.id.btn_invokeAIDLServer);
textView = (TextView) findViewById(R.id.textView);
btnStartAIDLServer.setEnabled(true);
btnStopAIDLServer.setEnabled(false);
btnInvokeAIDLServer.setEnabled(false);
btnStartAIDLServer.setOnClickListener(this);
btnStopAIDLServer.setOnClickListener(this);
btnInvokeAIDLServer.setOnClickListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
try {
if (null != mServer) {
mServer.unregisterCallback(mIAIDLCallback);
}
} catch (RemoteException e) {
}
if (bind_flag) {
unbindService(serviceConnection);//bind,unbind成对使用,不然会报错。。。
}
}
private void onClick() {
print("onClick");
bindService(new Intent("com.example.aidl"), serviceConnection,
Context.BIND_AUTO_CREATE);
bind_flag = true;
btnStartAIDLServer.setEnabled(false);
btnStopAIDLServer.setEnabled(true);
btnInvokeAIDLServer.setEnabled(true);
}
private void onCancelClick() {
print("onCancelClick");
unbindService(serviceConnection);
bind_flag = false;
btnStartAIDLServer.setEnabled(true);
btnStopAIDLServer.setEnabled(false);
btnInvokeAIDLServer.setEnabled(false);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_startAIDLServer:
onClick();
textView.setText("开始");
break;
case R.id.btn_stopAIDLServer:
onCancelClick();
textView.setText("停止");
break;
case R.id.btn_invokeAIDLServer:
try {
textView.setText("调用server方法:" + mServer.getValue());
} catch (Exception e) {
}
break;
}
}
}