Update:
右键单击项目树并添加一个名为 IMyAidlInterface.aidl 的新 AIDL 文件:
package com.test.aidlsample;
import com.test.aidlsample.MyData;
interface IMyAidlInterface {
List<MyData> getData(long id);
}
如果您需要将对象返回给客户端,您需要将它们声明并定义为可分割的,并将它们导入到aidl文件中,这里是MyData.aidl,应该位于其他aidl文件旁边:
package com.test.aidlsample;
// Declare MyData so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable MyData;
这是 java 文件夹中的 MyData.java:
public class MyData implements Parcelable {
private long productId;
private String productName;
private long productValue;
public MyData(long productId, String productName, long productValue) {
this.productId = productId;
this.productName = productName;
this.productValue = productValue;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(this.productId);
dest.writeString(this.productName);
dest.writeLong(this.productValue);
}
protected MyData(Parcel in) {
this.productId = in.readLong();
this.productName = in.readString();
this.productValue = in.readLong();
}
public static final Parcelable.Creator<MyData> CREATOR = new Parcelable.Creator<MyData>() {
@Override
public MyData createFromParcel(Parcel source) {
return new MyData(source);
}
@Override
public MyData[] newArray(int size) {
return new MyData[size];
}
};
}
现在构建项目,以便构建存根类。成功构建后继续服务:
public class SdkService extends Service {
private IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
@Override
public List<MyData> getData(long id) throws RemoteException {
//TODO: get data from db by id;
List<MyData> data = new ArrayList<>();
MyData aData = new MyData(1L, "productName", 100L);
data.add(aData);
return data;
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
return binder;
}
}
并将服务添加到 sdk 清单中。如果您将 sdk 添加为客户端的依赖项,例如:implementation project(':sdk')
您不需要将 AIDL 文件添加到客户端。如果没有,您必须添加它们并构建客户端应用程序。现在,只剩下实现客户端活动了:
public class MainActivity extends AppCompatActivity {
IMyAidlInterface mService;
/**
* Class for interacting with the main interface of the service.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
// This is called when the connection with the service has been
// established, giving us the service object we can use to
// interact with the service. We are communicating with our
// service through an IDL interface, so get a client-side
// representation of that from the raw service object.
mService = IMyAidlInterface.Stub.asInterface(service);
try {
List<MyData> data = mService.getData(1L);
updateUi(data);
} catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
}
public void onServiceDisconnected(ComponentName className) {
// This is called when the connection with the service has been
// unexpectedly disconnected -- that is, its process crashed.
mService = null;
}
};
private void updateUi(List<MyData> data) {
//TODO: Update UI here
}
@Override
protected void onResume() {
if (mService == null) {
Intent serviceIntent = new Intent();
//CAREFUL: serviceIntent.setComponent(new ComponentName("your.client.package", "your.sdk.service.path"));
serviceIntent.setComponent(new ComponentName("com.test.sampleclient", "com.test.aidlsample.SdkService"));
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE);
} else {
try {
updateUi(mService.getData(1L));
} catch (RemoteException e) {
e.printStackTrace();
}
}
super.onResume();
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
每次您的客户端活动获得可见性时,它都会从 SDK 服务获取数据。只需在此模板上构建您的逻辑即可。在 sdk 活动中将数据保存到数据库并在服务中从数据库中查询它们。我在此示例中使用了简单的参数。
我假设你的 sdk 是客户端应用程序中的一个库。如果没有,您可能需要做一些小的修改。正如我之前提到的,您可以在这里找到更多详细信息:Android 接口定义语言 (AIDL)。关于该主题的 SO 中有很多示例,甚至还有更多问答。祝你好运。
原来的:您需要从当前不可见的 Activity 获取回调,因为您的 SDK Activity 位于前面,对吗?为此,您可以为 SDK 创建数据库,将数据保存到数据库并通过AIDL在开始活动中:
SdkService sdkService;
CallbackData callbackData
private ServiceConnection mConnection = new ServiceConnection() {
// Called when the connection with the service is established
public void onServiceConnected(ComponentName className, IBinder service) {
sdkService = SdkService.Stub.asInterface(service);
}
// Called when the connection with the service disconnects unexpectedly
public void onServiceDisconnected(ComponentName className) {
Log.e(TAG, "Service has unexpectedly disconnected");
sdkService = null;
}
};
在 onCreate 中:
Intent i = new Intent()
i.setClassName("your.sdk.packageName", "your.sdk.service.path.and.name");
bindService(i, mConnection, Context.BIND_AUTO_CREATE);
并在需要时:
if(sdkService != null){
callbackData = sdkService.getCallbacks();
updateUI();
}
请注意,获取活页夹是一项异步作业,因此如果您调用 bindService 并在调用 sdkService.getCallbackData 之后立即收到 NullPointerException。因此,您可能希望将 getCallbacks 和 updateUI 移至 onServiceConnected 内,并在 onResume 中调用 bindService ,以便每次活动可见时,您都会检查是否存在 CallbackData,以便可以更新您的 UI 或其他内容。