Обновление:
Щелкните правой кнопкой мыши дерево проекта и добавьте новый файл AIDL с именем IMyAidlInterface.aidl:
package com.test.aidlsample;
import com.test.aidlsample.MyData;
interface IMyAidlInterface {
List<MyData> getData(long id);
}
Если вам нужно вернуться Объекты для вашего клиента, вам необходимо объявить и определить их как parcelable и импортировать их также в файл helpl, вот MyData.aidl, который должен быть рядом с другим файлом helpl:
package com.test.aidlsample;
// Declare MyData so AIDL can find it and knows that it implements
// the parcelable protocol.
parcelable MyData;
, а это MyData. java в папке 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. Просто создайте свой logi c поверх этого шаблона. В активности sdk сохранять данные в базу данных, а в сервисе запрашивать их из базы данных. В этом примере я использовал простые параметры.
Я предполагал, что ваш sdk - это библиотека в клиентском приложении. Если нет, возможно, вам нужно внести небольшие изменения. И, как я уже упоминал ранее, вы можете найти более подробную информацию здесь: Android Язык определения интерфейса (AIDL) . Здесь, в SO, есть много примеров и еще больше вопросов и ответов по этой теме. Удачи.
Оригинал: Вам нужно получать обратные вызовы от активности, которая в настоящее время невидима, так как ваша активность SDK находится впереди, верно? Для этого вы можете создать базу данных для своего 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();
}
Просто будьте осторожны, получение связующего - это асинхронное c задание, поэтому, если вы вызываете bindService и сразу после вызова sdkService.getCallbackData вы получаете исключение NullPointerException. Таким образом, вы можете переместить getCallbacks и updateUI внутри onServiceConnected и вызвать bindService в onResume, чтобы каждый раз, когда активность становится видимой, вы должны проверять, есть ли CallbackData, чтобы вы могли обновить свой пользовательский интерфейс или что-то еще.