【问题标题】:Android Service-Activity 2 way communicationAndroid Service-Activity 2路通信
【发布时间】:2012-02-28 20:19:44
【问题描述】:

在我团队的 Android 应用程序中,我有一个从启动时运行的服务,它与服务器通信以执行登录、注册、手机之间聊天和更新手机数据库等操作。

我需要让我的服务与活动进行双向通信:例如,我目前正在处理登录活动,用户名和密码是从应用程序屏幕上的文本字段中获取的字符串,我已经能够将它们传递给服务,以便它向服务器发送授权命令。

public void loginPressed(View v){
    usernameStr = usernameField.getText().toString();
    passwordStr = passwordField.getText().toString();

    if (!bound) return;
    Bundle b = new Bundle();
    Message msg = Message.obtain(null, ChatService.LOGIN);
    try {
        b.putString("username", usernameStr);
        b.putString("password", passwordStr);
        msg.setData(b);
        messenger.send(msg);
    }
    catch (RemoteException e) {

    }

这符合我的预期。当服务器响应一条消息说登录是否成功时,我需要它向活动传递一条消息,以便在成功时启动主要活动,否则提示重新进入。

我尝试使用 msg.replyTo 字段让返回信使将信息发回,但是当我运行应用程序时,它会强制关闭并出现空指针异常,我不知道为什么会这样。这是似乎是罪魁祸首的代码:

private class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch(msg.what) {
        case LOGIN:

            Bundle b = msg.getData();
            String username = b.getString("username");
            String password = b.getString("password");

            String loginMessage = TCPCall.login(username, password);
            connection.sendMessage(loginMessage);

            String loginReturn = connection.retrieveMessage();
            Message m;

            Scanner s = new Scanner(loginReturn);
            s.useDelimiter(",");
            String c = s.next();
            String status = s.next();
            String message = s.next();

            if (status.equals("OK")) {
                m = Message.obtain(null, LoginActivity.OK);
                try {
                    msg.replyTo.send(m);
                } catch (RemoteException e) {}
            }
            else {
                m = Message.obtain(null, LoginActivity.ERR);
                try {
                    msg.replyTo.send(m);
                } catch (RemoteException e) {}
            }
            break;

空指针似乎来自于

msg.replyTo.send(m);

两种情况下的代码行(登录成功和登录失败)

任何解决此问题的帮助将不胜感激:)

【问题讨论】:

  • 我对replyTo 字段不是很熟悉...但是,您的replyTo 消息成员似乎为空。您需要在发送原始消息时分配它。例如添加 'msg.replyTo = messenger;'
  • 如果格雷格的解决方案正确,有人可以回答吗?代码看起来已经足够好了,而且它没有使用 AIDL 或其他复杂的东西......
  • 格雷格的回答是正确的。在这里阅读:survivingwithandroid.com/2014/01/…

标签: java android service handler messenger


【解决方案1】:

正如 Gregg 在 cmets 中指出的那样。你需要在你发送原始消息的地方设置msg.replyTo = messenger;

可以在此处找到示例:http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html

【讨论】:

    【解决方案2】:

    我认为您忘记通过服务包发送对登录活动的响应。 所以,我在 Messenger 服务中做了一些更改

    定义一个全局变量并在 Incoming Handler 中进行一些更改

    static final int LOGIN_STATUS = 1;
    
    private class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch(msg.what) {
        case LOGIN:
    
            Bundle b = msg.getData();
            String username = b.getString("username");
            String password = b.getString("password");
    
            String loginMessage = TCPCall.login(username, password);
            connection.sendMessage(loginMessage);
    
            String loginReturn = connection.retrieveMessage();
            Message m = Message.obtain(null, LOGIN_STATUS);
    
            Scanner s = new Scanner(loginReturn);
            s.useDelimiter(",");
            String c = s.next();
            String status = s.next();
            String message = s.next();
    
            if (status.equals("OK")) {
                b.putString("responseC",c);
                b.putString("responseStatus",status);
                b.putString("responseMessage",message)
    
                m.setData(b);
                try {
                    msg.replyTo.send(m);
                } catch (RemoteException e) {}
            }
            else {
               /*if something is wrong with username and password you can put 
               a toast*/
    
                }
            break;
    

    现在我们必须在 LoginActivity 和 在 Login Activity 中也使用 IncomingHandler

    class IncomingHandler extends Handler{
    
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what){
                    case ChatService.LOGIN_STATUS:
                        String C = msg.getData().getString("responseC");
                        String Status = msg.getData().getString("responseStatus");
                        String Message = msg.getData().getString("responseMessage");
    
                        //Here is your response in LoginActivity, enjoy!!! 
    
                        break;
    
                    default:
                        super.handleMessage(msg);
                }
            }
        }
    
    final Messenger mMessenger = new Messenger(new IncomingHandler());
    
    public void loginPressed(View v){
    usernameStr = usernameField.getText().toString();
    passwordStr = passwordField.getText().toString();
    
    if (!bound) return;
    Bundle b = new Bundle();
    Message msg = Message.obtain(null, ChatService.LOGIN_SATUS,0,0);
    try {
        b.putString("username", usernameStr);
        b.putString("password", passwordStr);
        msg.setData(b);
        msg.replyTo = mMessenger;
        messenger.send(msg);
    }
    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.
    
    }
    

    此代码运行良好,希望对您有所帮助, 谢谢

    【讨论】:

      猜你喜欢
      • 2013-01-19
      • 1970-01-01
      • 2012-05-17
      • 1970-01-01
      • 2016-03-07
      • 2014-01-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多