【问题标题】:Android : Bound service handling multiple messages simultaneously from clientAndroid:绑定服务同时处理来自客户端的多条消息
【发布时间】:2016-03-06 15:20:03
【问题描述】:

这是我的问题: 为了简化,我使用了一个 IntentService,它使用 Messenger 对象处理一对消息,第一条消息 (msg.what==1) 启动 10 秒进程,第二条消息 (msg.what==2) 启动 5 秒进程.这些消息是由绑定到我的服务的第三方 Activity 发送的,它正在等待对这些发送的消息的回复。

一切正常,但如果消息 1 正在运行,则在发送消息 2 时,它会等到第一个进程完成后再进行处理。当我阅读本文时,意图服务的预期行为(消息在外部线程中按顺序排队和处理)。

但是当前一个消息仍在运行时,是否有一个技巧可以对新发送的消息进行异步响应?(即在消息 1 仍在运行时获得对消息 2 的回复)我试过了在我的 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();
            }
        }
    }

感谢您的建议。

【问题讨论】:

  • 你到底想达到什么目标?
  • 想象一下我发送消息 1,然后我立即从我的活动中发送消息 2。消息 2 不会立即处理,而是排队。所以我在 10 秒(处理消息 1)+ 5 秒(处理已排队的消息 2)后得到它的响应。我希望仅在 5 秒后收到对消息 2 的回复(无需等待消息 1 进程完成)
  • 它已排队,因为您使用的是 IntentService,它为所有请求使用一个后台线程,如果您想立即处理您的消息,请使用 "one Message - one Thread" 方法
  • 如果这种方法在活动和服务之间使用双边对话,你能给我举个例子吗?

标签: android multithreading service messenger


【解决方案1】:

好的,考虑 pskink 的链接 (http://pastebin.com/L1m3NJTT)

这是我尝试过的:我现在扩展了服务,不再扩展 IntentService。而我的 Handler 现在是

class IncomingHanlder extends Handler {
    @Override
    public void handleMessage(Message msg)  {
        pool.submit(new MyRunnable(msg));
        super.handleMessage(msg);
    }
}

此方法必须获取传入消息 (msg) 才能允许使用 replyto 方法,在 myRunnable 方法中是

public class MyRunnable implements Runnable {
private final Message _message;
public MyRunnable(final Message message) {
    this._message = message;
}


@Override
public void run() {
try {
    switch (this._message.what) {

        case 1:
            //Process taking 10 sec
            //...

            //Reply to client
            Message resp = Message.obtain(null, this._message.what);
            Bundle bResp = new Bundle();
            bResp.putBoolean("com.xxx.msg1", true);
            resp.setData(bResp);
            this._message.replyTo.send(resp);
            break;

        case 2:
            //Process taking 5 sec
            //...

            //Reply to client
            Message resp = Message.obtain(null, this._message.what);
            Bundle bResp = new Bundle();
            bResp.putBoolean("com.xxx.msg2", true);
            resp.setData(bResp);
            this._message.replyTo.send(resp);
            break;

        default:

    }
}
    catch (RemoteException e) {
        e.printStackTrace();
    }
}

}

请注意,我仍然使用服务接口 onBind 实现:

private Messenger msg = new Messenger(new ConvertHanlder());

  @Override
public IBinder onBind(Intent arg0) {
    return msg.getBinder();
}

事实是:我现在在发送消息的活动中从未得到任何答案。我错过了什么吗?

【讨论】:

    猜你喜欢
    • 2017-06-18
    • 2017-12-26
    • 1970-01-01
    • 2017-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多