Вот моя проблема: для упрощения я использую IntentService, который обрабатывает пару сообщений с использованием объекта Messenger, первое сообщение (msg.what==1) запускает 10-секундный процесс, второе (msg.what==2) запустить 5-секундный процесс. Эти сообщения отправляются сторонней активностью, которая привязана к моей службе и ожидает ответа на эти отправленные сообщения.
Все работает нормально, но если сообщение 1 запущено, при отправке сообщения 2 оно будет ждать, пока не будет выполнен первый процесс для обработки. Когда я прочитал это, ожидаемое поведение с Intent Service (сообщения ставятся в очередь и обрабатываются последовательно во внешнем потоке).
Но есть ли способ получить асинхронный ответ на новое отправленное сообщение, когда предыдущее все еще выполняется? (т.е. получить ответ на сообщение 2, когда сообщение 1 все еще выполняется) Я пытался использовать поток и asynctask для моей функции handleMessage безуспешно (я даже не получаю ответа на свой запрос в действии)
Класс обслуживания: обработчик
class IncomingHanlder extends Handler {
@Override
public void handleMessage(Message msg) {
try {
switch (msg.what) {
case 1:
//Process taking 10 sec
//...
//Reply to client
Message resp = Message.obtain(null, msg.what);
Bundle bResp = new Bundle();
bResp.putBoolean("com.xxx.msg1", true);
resp.setData(bResp);
msg.replyTo.send(resp);
break;
case 2:
//Process taking 5 sec
//...
//Reply to client
Message resp = Message.obtain(null, msg.what);
Bundle bResp = new Bundle();
bResp.putBoolean("com.xxx.msg2", true);
resp.setData(bResp);
msg.replyTo.send(resp);
break;
default:
super.handleMessage(msg);
}
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
private Messenger msg = new Messenger(new IncomingHanlder ());
@Override
public IBinder onBind(Intent arg0) {return msg.getBinder();}
Класс клиента: активность (стороннее приложение)
ServiceConnection sConn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName name) {
messenger = null;
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
// We are connected to the service
messenger = new Messenger(service);
}
};
// We bind to the service
Intent i = new Intent("com.xxx.myserviceboundpackage");
try {
//If service is always launched
stopService(i);
}
catch (Exception e){}
//Bind to service
bindService(i, sConn,
Context.BIND_AUTO_CREATE);
В клиенте: отправка сообщения нажатием кнопки (например, сообщение 1)
try {
Message msg = Message
.obtain(null, 1);
msg.replyTo = new Messenger(new ResponseHandler());;
try {
messenger.send(msg);
} catch (RemoteException e) {
}
}
catch (Exception e)
{
e.printstacktrace();
}
В клиенте: обработка сообщения от ответа службы на
class ResponseHanlder extends Handler {
@Override
public void handleMessage(Message msg) {
try {
switch (msg.what) {
//Response to each request
case 1:
//Process which have taken 10 sec
Bundle bundle = msg.getData();
Boolean myResp = bundle.getBoolean("com.xxx.msg1");
if (myResp) {//do something}
break;
case 2:
//Process which have taken 5 sec
Bundle bundle = msg.getData();
Boolean myResp = bundle.getBoolean("com.xxx.msg2");
if (myResp) {//do something}
break;
default:
super.handleMessage(msg);
}
}
catch (RemoteException e) {
e.printStackTrace();
}
}
}
Спасибо за предложение.
IntentService
, который использует один фоновый поток для всех запросов, если вы хотите немедленно обрабатывать свои сообщения, используйте подход"one Message - one Thread"
- person pskink   schedule 02.12.2015pool.submit
внутрьhandleMessage
- person pskink   schedule 02.12.2015