У меня есть два приложения, приложение A и приложение B.
A - это просто служба, которая запускается при ЗАГРУЗКЕ COMPLETE и перезапускается, если она уничтожена.
Постоянно получает сообщения (через последовательное соединение, но это не имеет значения).
Если сообщение получено, но никакие другие приложения не привязаны к службе, меня не волнует сообщение, и оно может быть потеряно.
Однако, если какое-то сообщение получено и, скажем, B привязано к нему, я хочу, чтобы B получил это сообщение.
Итак, я попытался использовать AIDL для передачи сообщения от A к B, но я не могу заставить его работать. Я, вероятно, что-то не так делаю здесь или использую его неправильно, поэтому я буду признателен за любую помощь здесь.
мой код в моей службе:
public class ExtProtocolService extends Service {
static RS232Comm serialComm;
public static final int BAUDRATE = 19200;
public static final int COM = 1;
public static Handler handler;
private Message message;
@Override
public IBinder onBind(Intent intent) {
return (new MessageBinder());
}
private static class MessageBinder extends IExtMessage.Stub {
@Override
public void receive(IExtMessageCallBack callback) {
new ReceiveThread(callback).
}
}
@Override
public void onCreate() {
serialComm = new RS232Comm(COM, BAUDRATE, 0, this);
handler=new Handler(){
@Override
public void handleMessage(Message msg) {
message=msg;
}
};
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(getApplicationContext(), "Protocol Service Started",
Toast.LENGTH_SHORT).show();
return START_STICKY;
}
public static class ReceiveThread implements Runnable {
int numCharsToRead = 2;
IExtMessageCallBack cb = null;
boolean ok;
ReceiveThread(IExtMessageCallBack cb) {
this.cb = cb;
}
@Override
public void run() {
try {
serialComm.Open();
ok = serialComm.Receive(numCharsToRead);
if (ok) {
cb.onSuccess();
}
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
RS232Comm serialComm — это класс, в котором я получаю свои сообщения, основной код:
Message message=Message.obtain();
Bundle bundle=new Bundle();
bundle.putInt("command", command);
bundle.putInt("messageLength", messageLength);
bundle.putString("wholeData", wholeData);
message.setData(bundle);
Toast.makeText(context.getApplicationContext(), "Valid", Toast.LENGTH_LONG).show();
ExtProtocolService.handler.sendMessage(message);
return true;
Как видите, я использую обработчик для передачи сообщения обратно в сервисный класс.
мои файлы AIDL:
interface IExtMessage{
void receive(IExtMessageCallBack callback);
}
а также :
interface IExtMessageCallBack{
void onSuccess();
void onFailure(String msg);
}
Теперь, приложение B, это просто основное действие, чтобы проверить, передано ли мое сообщение:
package com.tfl.testmyservice;
public class MainActivity extends Activity implements ServiceConnection {
public static final String TAG = "YANIV";
private IExtMessage binding;
private Application appContext = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent implicit = new Intent(IExtMessage.class.getName());
List<ResolveInfo> matches = getPackageManager().queryIntentServices(
implicit, 0);
if (matches.size() == 0) {
Toast.makeText(getApplicationContext(),
"Cannot find a matching service!", Toast.LENGTH_LONG)
.show();
} else if (matches.size() > 1) {
Toast.makeText(getApplicationContext(),
"Found multiple matching services!", Toast.LENGTH_LONG)
.show();
} else {
Intent explicit = new Intent(implicit);
ServiceInfo svcInfo = matches.get(0).serviceInfo;
ComponentName cn = new ComponentName(
svcInfo.applicationInfo.packageName, svcInfo.name);
explicit.setComponent(cn);
bindService(explicit, this, Context.BIND_WAIVE_PRIORITY);
}
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
binding = IExtMessage.Stub.asInterface(binder);
}
@Override
public void onServiceDisconnected(ComponentName name) {
binding = null;
}
public void onEventMainTread(CallbackEvent event){
if(event.succeeded){
Toast.makeText(this, "Success", Toast.LENGTH_LONG).show();
}
else{
Toast.makeText(this, event.msg, Toast.LENGTH_LONG).show();
}
}
IExtMessageCallBack.Stub cb=new IExtMessageCallBack.Stub() {
@Override
public void onSuccess() throws RemoteException {
new CallbackEvent(true, null);
}
@Override
public void onFailure(String msg) throws RemoteException {
new CallbackEvent(false, msg);
}
};
static class CallbackEvent{
boolean succeeded=false;
String msg=null;
public CallbackEvent(boolean succeeded,String msg) {
this.succeeded=succeeded;
this.msg=msg;
}
}
}
Те же AIDL есть и в приложении B.
вывод, который я получаю, - "подходящие сервисы не найдены!"
просто хочу отметить, что сервис сам по себе работает отлично. просто когда я пробую этот IPC с помощью AIDL, все становится немного запутанным.