想要实现一个夸进程,从app1向app2请求数据,并且app2收到请求回调给app1
建立aidl文件 IMyService.aidl
package com.example.shenwchneusoftcom.testaidlone;
import com.example.shenwchneusoftcom.testaidlone.Product;
import com.example.shenwchneusoftcom.testaidlone.ITaskCallback;
interface IMyService 实现一个接口
{
Map getMap(in String country, in Product product); //实现map的方法
Product getProduct(); //实现getProduct的方法
void getProduc(out Product product); //实现 带参数的方法
//用来注册回调的对象
void registerCallback(ITaskCallback cb); //注册callback
void unregisterCallback(ITaskCallback cb); //取消注册callback
void startCallBack(); //请求callback的方法
}
ITaskCallback.aidl
用来回调给app端传输方法
package com.example.shenwchneusoftcom.testaidlone;
//该接口在客户端实现
//private ITaskCallback mCallback = new ITaskCallback.Stub() {
// @Override
// public void clientTackCallBack(int actionId) throws RemoteException {
// Log.i(TAG, "actionId :" + actionId);
// }
// };
interface ITaskCallback {
//客户端给服务器端回调的函数,
//前提是当客户端获取的IBinder接口的时候,要去注册回调函数, 只有这样, 服务器端才知道该调用哪些函数
//void registerCallback(ITaskCallback cb);注册的函数,在IMyService.aidl文件中
//void unregisterCallback(ITaskCallback cb);取消注册的函数,在IMyService.aidl文件中
//客户端调用myService.registerCallback(mCallback);
void clientTackCallBack(int actionId);
}
建立可序列化的实例
parcelable Product;
建立服务
package com.example.shenwchneusoftcom.testaidlone;
import java.util.HashMap;
import java.util.Map;
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 MyService extends Service
{
private final static String TAG = "***MyService***";
//用来注册客户端回调接口对象
private RemoteCallbackList mCallbacks;
@Override
public void onCreate() {
Log.d(TAG, "myService onCreate()");
super.onCreate();
mCallbacks = new RemoteCallbackList();
callback(100); //用来测试
}
@Override
public void onStart(Intent intent, int startId) {
Log.d(TAG, "startId :" + startId);
callback(startId);//用来测试
}
void callback(int startId) {
final int N = mCallbacks.beginBroadcast(); 获取callback的次数
Log.d(TAG, "mCallbacks.beginBroadcast() :" + N);
for (int i = 0; i < N; i++) {
try {
mCallbacks.getBroadcastItem(i).clientTackCallBack(startId); 传递给客户端的回调
} catch (RemoteException e) {
// The RemoteCallbackList will take care of removing
// the dead object for us.
}
}
mCallbacks.finishBroadcast();结束callback
}
//通过binder数据实现
public class MyServiceImpl extends IMyService.Stub
{
@Override
public Product getProduct() throws RemoteException
{
//app端调用该方法,服务端提供的数据
Product product = new Product();
product.setId(1234);
product.setName("汽车");
product.setPrice(31000);
return product;
}
@Override
public void getProduc(Product product) throws RemoteException {
//app端调用该方法,服务端提供的数据
if(product == null) product = new Product();
product.setId(1234);
product.setName("飞机");
product.setPrice(62000);
}
@Override
public Map getMap(String country, Product product)
throws RemoteException
{
//app端调用该方法,服务端提供的数据
Map map = new HashMap();
map.put("country", country);
map.put("id", product.getId());
map.put("name", product.getName());
map.put("price", product.getPrice());
map.put("product", product);
return map;
}
@Override
public void registerCallback(ITaskCallback cb) throws RemoteException {
if(cb != null)
//注册RemoteCallbackList
mCallbacks.register(cb);
}
@Override
public void unregisterCallback(ITaskCallback cb) throws RemoteException {
if(cb != null)
//解除注册RemoteCallbackList
mCallbacks.unregister(cb);
}
@Override
public void startCallBack() throws RemoteException {
//App端请求该方法,并回调给app端
callback(2000);
}
}
@Override
public IBinder onBind(Intent intent)
{
return new MyServiceImpl();
}
}
实体类
该文件一定要与aidl文件同目录下,要不然aidl里面是找不到该实例的
package com.example.shenwchneusoftcom.testaidlone;
import android.os.Parcel;
import android.os.Parcelable;
public class Product implements Parcelable
{
private int id;
private String name;
private float price;
public static final Creator CREATOR = new Creator()
{
public Product createFromParcel(Parcel in)
{
return new Product(in);
}
public Product[] newArray(int size)
{
return new Product[size];
}
};
public Product()
{
}
private Product(Parcel in)
{
readFromParcel(in);
}
@Override
public int describeContents()
{
// TODO Auto-generated method stub
return 0;
}
public void readFromParcel(Parcel in)
{
id = in.readInt();
name = in.readString();
price = in.readFloat();
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeInt(id);
dest.writeString(name);
dest.writeFloat(price);
}
public int getId()
{
return id;
}
public void setId(int id)
{
this.id = id;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public float getPrice()
{
return price;
}
public void setPrice(float price)
{
this.price = price;
}
}
AndroidManifest.xml
将服务端的aidl放到app端下aidl并且包名一定要一致,要不然服务端是找不到app端的
客户端代码
package com.example.shenwchneusoftcom.testaidloneclient;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
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 android.widget.Toast;
import com.example.shenwchneusoftcom.testaidlone.IMyService;
import com.example.shenwchneusoftcom.testaidlone.ITaskCallback;
import com.example.shenwchneusoftcom.testaidlone.Product;
public class Main extends Activity implements OnClickListener
{
private final static String TAG = "***Main***";
private IMyService myService = null;
private Button btnInvokeAIDLService;
private Button btnBindAIDLService;
private Button btnStartCallBack;
private TextView textView;
private ServiceConnection serviceConnection = new ServiceConnection()
{
@Override
public void onServiceConnected(ComponentName name, IBinder service)
{
myService = IMyService.Stub.asInterface(service); //获取服务端
try {
myService.registerCallback(mCallback); //注册callback
} catch (RemoteException e) {
e.printStackTrace();
}
btnInvokeAIDLService.setEnabled(true);
}
@Override
public void onServiceDisconnected(ComponentName name)
{
// TODO Auto-generated method stub
}
};
@Override
protected void onPause() {
super.onPause();
try {
myService.unregisterCallback(mCallback);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onClick(View view)
{
switch (view.getId())
{
case R.id.btnBindAIDLService:
//启动服务端服务
Intent mIntent = new Intent();
mIntent.setAction("com.example.shenwchneusoftcom.testaidlone.IMyService");
bindService(getExplicitIntent(this,mIntent), serviceConnection, Context.BIND_AUTO_CREATE);
// startService(new Intent("com.example.shenwchneusoftcom.testaidlone.IMyService"));
break;
case R.id.btnInvokeAIDLService:
try
{
Product product = new Product();
String s = "";
s = "Product.id = " + myService.getProduct().getId() + "\n";
s += "Product.name = " + myService.getProduct().getName()
+ "\n";
s += "Product.price = " + myService.getProduct().getPrice()
+ "\n\n";
myService.getProduc(product);
s += "Product.id = " + product.getId() + "\n";
s += "Product.name = " + product.getName()
+ "\n";
s += "Product.price = " + product.getPrice()
+ "\n\n";
s += myService.getMap("China", myService.getProduct()).toString();
textView.setText(s);
}
catch (Exception e)
{
}
break;
case R.id.btnStartCallBack:
//app端主动获取callback方法
if (myService!=null){
try {
Log.d(TAG, "btnStartCallBack" );
myService.startCallBack();
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
}
}
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnInvokeAIDLService = (Button) findViewById(R.id.btnInvokeAIDLService);
btnBindAIDLService = (Button) findViewById(R.id.btnBindAIDLService);
btnStartCallBack = (Button)findViewById(R.id.btnStartCallBack);
btnInvokeAIDLService.setEnabled(false);
textView = (TextView) findViewById(R.id.textview);
btnInvokeAIDLService.setOnClickListener(this);
btnBindAIDLService.setOnClickListener(this);
btnStartCallBack.setOnClickListener(this);
}
private ITaskCallback mCallback = new ITaskCallback.Stub() {
@Override
public void clientTackCallBack(int actionId) throws RemoteException {
//app端主动获取方法之后,服务端提供的回调
Log.d(TAG, "actionId :" + actionId);
}
};
//显示启动
private static Intent getExplicitIntent(Context context,Intent implicitIntent) {
PackageManager pm = context.getPackageManager();
ResolveInfo resolveInfo = pm.resolveService(implicitIntent, 0);
ComponentName component = new ComponentName(resolveInfo.serviceInfo.packageName, resolveInfo.serviceInfo.name);
// 创建一个新的意图。使用旧的一个额外的和这样的重用
Intent explicitIntent = new Intent(implicitIntent);
// 将组件设置为显式
explicitIntent.setComponent(component);
return explicitIntent;
}
}
并且实例 Product是与服务端一样的
总结:
就是跨进程的接口回调与接口调用,只不过都是靠aidl(binder)统一管理实现跨进程
(借鉴https://www.jianshu.com/p/b260051237fe)