使用场景
由于业务需求,可能我们在开发Android SDK项目的时候会遇到这样一种情况,就是当手机ROM中有多个应用需要调用同一个sdk。当然将我们的sdk每个应用放一个jar包不太合适,如何做到只用一份sdk供所有的应用调用呢?可以想到的方案是,我们将我们的sdk放到自己的apk中封装一下,然后让其他应用都调用同一个apk开放的接口。那么问题来了,如何调用外部应用的接口呢,这就涉及到我们今天讲的主题--使用AIDL的方式进行进程间的通信。
基本原理
简单示例:
package com.example.testaidlclient;
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.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import com.example.testaidlserver.MyAIDLService;
import com.example.testaidlserver.ShopItem;
public class MainActivity extends Activity implements OnClickListener {
private Button bind,get;
private TextView tv_shopItem;
private ShopItem shopItem;
private MyAIDLService mRemoteService;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv_shopItem = (TextView) findViewById(R.id.tv_shopItem);
get = (Button) findViewById(R.id.getShopItem);
bind = (Button) findViewById(R.id.bindRemoteService);
bind.setOnClickListener(this);
get.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bindRemoteService:
this.bindService(new Intent("com.example.remoteservice"), conn, Context.BIND_AUTO_CREATE);
break;
case R.id.getShopItem:
if (mRemoteService != null) {
try {
shopItem = mRemoteService.getShopItem();
tv_shopItem.setText("ShopItem:"+"id="+shopItem.getId()+"\nshopName="+shopItem.getName());
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
default:
break;
}
}
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mRemoteService = MyAIDLService.Stub.asInterface(service);
try {
mRemoteService.startDetailActivity();
} catch (RemoteException e) {
e.printStackTrace();
}
}
};
}
package com.example.testaidlserver;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
/**
* @author YULORE-USER
*/
public class RemoteService extends Service {
public static String TAG = RemoteService.class.getSimpleName();
@Override
public IBinder onBind(Intent intent) {
return mRemoteServiceBinder;
}
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand is called!");
return super.onStartCommand(intent, flags, startId);
};
MyAIDLService.Stub mRemoteServiceBinder = new MyAIDLService.Stub(){
@Override
public void startDetailActivity() throws RemoteException {
ComponentName cn = new ComponentName("com.example.testaidlserver", "com.example.testaidlserver.ShopDetailActivity");
Intent intent = new Intent("com.example.testaidlserver.shopdetail");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
@Override
public ShopItem getShopItem() throws RemoteException {
ShopItem item = new ShopItem();
item.setId(100);
item.setName("remote service");
return item;
}
};
}
package com.example.testaidlserver;
import com.example.testaidlserver.ShopItem;
interface MyAIDLService {
void startDetailActivity();
ShopItem getShopItem();
}
ShopItem.aidl
package com.example.testaidlserver;
parcelable ShopItem;
package com.example.testaidlserver;
import android.os.Parcel;
import android.os.Parcelable;
public class ShopItem implements Parcelable{
private String name;
private int id;
public ShopItem(){}
public ShopItem(Parcel par){
id = par.readInt();
name = par.readString();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(name);
}
public static final Parcelable.Creator<ShopItem> CREATOR = new Creator<ShopItem>() {
@Override
public ShopItem[] newArray(int size) {
return new ShopItem[size];
}
@Override
public ShopItem createFromParcel(Parcel source) {
return new ShopItem(source);
}
};
}